没有合适的资源?快使用搜索试试~ 我知道了~
理论计算机科学电子笔记102(2004)63-75www.elsevier.com/locate/entcsOclType斯蒂芬·弗莱克1C-LAB,帕德博恩大学Fuerstenallee 1133102帕德博恩,德国摘要虽然在最新的OCL 2.0提案的OCL标准库中提出的类型系统似乎 到目前为止,要想变得相当稳定,在类型转换和类型一致性检查的操作定义方面仍然存在一些缺陷。这是因为用户级定义的类型目前在OCL标准库中没有很好的表示。本文提出了一种新的建模方法,通过称为powertype的UML核心概念在OCL标准库powertype概念允许在架构用户级别M1上对元元素建模。通过这种方法,我们提出了一个增强结构的OCL标准库,规定了一个控制的方式访问元级。关键词:OCL标准库,Powertype1介绍虽然采用了最新的1.6版本的响应UML2.0 OCL Request for Proposals(以下简称OCL 2.0提案)是该语言发展的重要一步,目前仍有一些问题需要解决。我们认为,在UML 2.0标准最终化之前,对OCL 2.0提案进行进一步的增强是非常重要的。否则,语言定义中的明显缺陷将阻止工具开发人员和用户采用OCL,因此OCL基本上仍然是一个作为另一个可能的后果,工具1电子邮件地址:flake@c-lab.de1571-0661 © 2004 Elsevier B. V.根据CC BY-NC-ND许可证开放访问。doi:10.1016/j.entcs.2003.09.00464S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-对于OCL 2.0规范中尚未解决的问题,构建者可以采用自己的解决方案。OCL 2.0提案目前既不一致也不完整,例如,一些新引入的概念,如OCL消息的形式语义没有得到充分的考虑。但是,作为UML 1.5的一部分,OCL中已经存在的概念仍然没有得到充分的定义,例如,尽管语法允许指定对状态激活的约束,但是没有为状态相关操作提供语义除了这些语义问题之外,本文还将重点关注OCL标准库中预定义类型OclType的改进因此,这项工作被视为对UML 2.0的OCL最终化过程1.1OCL 2.0提案中的OclTypeOCL是一种类型化的表达式语言,包括一组预定义的类型,如String、String和Real。它们被保存在一个类型系统中,该类型系统是所谓的OCL标准库的一部分,位于UML 4层体系结构的M1层[4,第6章]。自然,在没有UML模型参考的情况下制定约束是没有意义的。在剩下的部分中,我们将把这个UML模型称为引用的UML用户模型。在所引用的UML用户模型中定义的每个Classifier2表示一个不同的OCL类型,并作为OclAny的子类型隐式地包含在OCL标准库中。在标准库的预定义OCL类型中,OclType具有特殊角色。该类型捕获OCL类型系统中已知的所有基本类型。3有趣的是,OclType一方面本质上是属于元级别M2的一种元元素,而另一方面它必须在用户级别M1上可访问,以制定需要推理对象类型的约束(例如,类型一致性检查)。OCL 2.0提案中采用的方法将OclType建模为枚举类型[4,第6.2节]。选择将OclType建模为枚举类型是因为不再支持对元级别的访问与OCL定义相反,OCL定义是当前UML 1.5标准的一部分[5,第6章]。图1以图形方式说明了OclType的拟议定义以及作为枚举字面量的预定义基本OCL类型我们有2更准确地说,我们必须说“元类型分类器的每个实例”,但我们在这里采用UML规范中使用的术语。我们把所有预定义的非参数化OCL类型称为基本类型。这包括所引用的UML用户模型的用户定义的分类器,并且不包括参数化类型,如集合类型和OCL消息类型。S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-65这个省略号(.) 表示给定UML模型的所有用户定义的分类器也成为OclType的枚举文字«枚举»OclTypeOclAnyOclTypeOclStateBooleanRealStringOclVoid(.)=(type = 0):Boolean<>(typical:OclType):BooleanFig. 1. 枚举类型OclType(在OCL 2.0提案中提出)使用了一个注释省略号来表示必须根据所引用的UML用户模型添加额外的枚举文字1.2使用OclType作为参数类型的操作在表1中,我们列出了OCL类型的集合和使用OclType的相应操作[4,6.2.1和6.3.1节]。请注意,文字T表示任意的基本OCL类型。表1OclType在OCL 2.0提案中的出现OCL类型操作签名OclAnyoclAsType(typical:OclType):oclIsTypeOf(typical:OclType):oclIsKindOf(typical:OclType):不布尔布尔OclModelElement=<>(object:Object)(object:Object)::布尔布尔OclType=<>(object:Object)(object:Object)::布尔布尔这些操作的签名已经存在许多问题。首先,操作=和<>的签名对于OclModelElement是错误的。OclModelElement类型在OCL 2.0建议中被视为枚举类型,对于给定UML用户模型中的每个元素OclModelElement必须存在-前包括所有用户定义的分类器,但也包括所有其他模型元素,如状态图状态,转换,事件,操作,信号等。虽然这种类型是否必要和有意义值得 怀 疑 , 但 必 须 纠 正 相 应 的 操 作 签 名 , 即 , 形 参 类 型 必 须 是OclModelElement而不是OclType。66S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-在OCL表达式中,有时需要访问用户定义的类的类型执行类型转换或检查某个子类型。在此上下文中,使用操作oclAsType(typical:OclType)。该操作返回一个对象,该对象被重新类型化为由实际参数类型指定的类型。4从概念上讲,这意味着必须访问元层M2来推理当前对象类型和指定目标类型之间的类型一致性由于OCL 2.0提案中采用的方法不可能做到这一点,因此以OCL后确认形式的正式规范不能为操作oclAsType(typical:OclType)、oclIsTypeOf(typical:OclType)和oclIsKindOf(typical:OclType)提供ditions。请注意,在OCL中,相应的段落标有2.0提案在下面的章节中,我们将考虑在文献(第2节)和当前OCL 2.0提案(第3节)中的不同方法中OclType类型的定义和使用在第4节中,我们将展示如何引入powertype概念,以更好地将在用户级别定义的类型集成到OCL标准库类型系统的M1级别。第5节结束本文。2相关工作有不同的可能性来提供对分类器的访问。UML 1.5中定义的当前标准使用OclType,并将其称为建模器可以访问的元类型[5,Section 6.8.1.1]:所有在UML模型中定义的类型,或者在OCL中预先定义的类型,都有一个类型。此类型是OCL类型的实例,称为OclType。 对该类型的访问允许建模者对模型的元级别进行有限的访问。在UML 1.5中,甚至为OclType提供了预定义的操作来进一步访问元级特性,例如,获取属性名称列表、关联结束名称以及直接和间接超类型名称的操作(但是,缺少提取子类型的操作)。因此,建模者能够访问OCL表达式中的元层。请注意,这打破了UML建模方法下面的4层体系结构。这个问题已经被识别出来,最近的OCL语言定义放弃了这些操作。BaarandHahnlesuggesttoomodelOclTypeasapureemetatypewithout4尽管有一些争论认为类型转换操作符不应该出现在特定语言中,但OCL 2.0提案给出了一个例子,其中这样的操作对于消除歧义是必要的[4,第2.5.8节]。S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-67模型的访问[1]。上面提到的操作不需要在它们的方法中在OclType上定义,因为UML核心元模型已经直接或间接地提供了这样的方法(通过沿着UML核心元模型中的关联导航在这方面还值得注意的是,他们的元模型不允许嵌套集合,而这在OCL 2.0提案中是允许Richters提出了一种名为OclTypeType的元类型,OclType是它在M1级别上的唯一实例[6,6.4节]。RichterOclType的实例都是OCL类型。 这种类型最有用的操作是allpark(),用于提取给定类型的所有当前存在对象的集合。此外,所引用的UML模型的所有分类器都被复制并存储在M1级别上的称为ObjectType从语义上讲,ObjectType实例的域是为Class及其子对象定义的对象标识符我们在本文中介绍的方法与w.r.t.类似。Richters3OclType的操作回顾正如在第1节中已经提到的,OclType在OCL 2.0提案中作为OclAny的子类型驻留在M1层。OclType被认为是包含所引用的UML用户模型的分类器名称的枚举。除了为OclType显式重新定义的操作=和<>之外,还有6个操作是从OclAny继承的(见表2)。表2OclAny的预定义操作=(object2:OclAny):<>(object2:OclAny):oclIsNew():public void run():oclAsType(typical:OclType):oclIsTypeOf( typical :OclType ) :oclIsKindOf(typical:oclInState(状态名:OclState):alert():布尔布尔T布尔 布尔布尔设置(T)现在我们简要回顾一下这些操作的语义,OclType。 注意,这里我们区分了databases的原始值68S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-例如OclType的枚举值或枚举文字,以及可以动态创建和销毁的类实例对象• 操作oclIsNew()在应用于数据类型值时必须返回false,因为原始值不能动态创建或销毁。这当然适用于OclType的枚举文字。(或者在这些情况下,该操作是否应该返回OclUndefinedOCL 2.0提案目前没有详细说明结果。• 根据定义,操作oclIsUndefined()在应用于数据类型值时必须始终返回false• 操作oclAsType(typical:OclType)返回一个对象,该对象被重新类型化为由实际参数typical指定的类型。我们在这里只提到OCL2.0中有一些相互矛盾的需求关于向上和向下的建议。这将在第3.1小节中更详细地讨论。• 一般来 说,如果 操作oclIsTypeOf( typical :OclType) 应用于 由typical指定的类型的对象或数据类型值,则其计算结果为true。当此操作应用于枚举文字时,注意到一个OCL类型,比如说,只有当参数类型是OclType时,求值结果才为真。因此,表达式Ocl.oclIsTypeOf(OclType)的计算结果为true,但对于与OclType不同的所有参数值,结果为false。这种语义适用于OCL类型系统的所有类型但这是预期的结果吗?也许不是,就像人们在这个骗局中所希望的那样text现在的问题是OCL类型的类型驻留在元级M2上,例如,元数据的类型是Primitive。但是这样的元数据在级别M1上的OCL类型系统中是未知的,因此将操作oclIsTypeOf(typical:OclType)应用于任何这样的枚举文字没有多大意义。• 如果操作oclIsKindOf(typical:OclType)应用于其类型符合typical指定的类型的对象或值,则其计算结果为true。当应用于表示OCL类型的枚举文字时,会出现与操作oclIsTypeOf()• 操作oclInState(状态名:OclState)在应用于数据类型值和枚举文字 时 没 有 意 义 。 在 这 种 情 况 下 , 它 应 该 返 回 OclUndefined 。operationoclInState(状态名:OclState)的一个完整的正式规范已经被开发出来,可以在[3]中找到。S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-69• 操作allpark()返回它所应用到的类型的所有实例。它只能用于具有有限数量实例的分类器(或类型),例如,用户定义的类[4,6.2.1节]。5下面的例子取自OCL 2.0提案。它将OCL类型OclVoid的实例数限制为1。上下文OclVoid投资者:OclVoid. alllog()->size()= 1个OclVoid 是OCL 类型, 即, 在上述OCL 表达式中,OclVoid 计算为OclType类型的枚举文字。现在,对枚举文字应用操作alllogn()作为另一个例子,现在假设一个用户定义的类Person和OCL表达式Person. allpark()。 同样,Person被标识为OclType的枚举文字,那么计算相应的OCL表达式的结果是什么,即,将operationallocation()应用于枚举文字的结果是什么?这显然是错误的体系结构级别,也不是故意的。总而言之,尝试将OclType建模为枚举类型,以便将预定义的OCL类型与元级别分离,这引入了几个与类型相关的困难另一方面,不可能用推理对象没有(有限)访问元级别的类型。在不访问元层的情况下,也不可能给出关于OCL类型的推理操作的语义。此外,将allpark()定义为基类型OclAny的操作是没有意义的,因为该操作应该只应用于类型而不是对象。不过,现时建议的八达通卡在类型系统中,M1类型不能被访问,因为用户定义的类(如Person)和OCL类型(如OclVoid)仅被视为枚举类型OclType的枚举文字。为了获得这个字面量所代表的类的对象集,将操作allpark()应用于一个枚举字面量,比如Person3.1在OCL 2.0提案中重新输入对象现在我们来仔细看看OclAny该操作返回相同的对象,但对象5然而,请注意,这个问题仍在争论中。最基本的问题是,OCL没有一个足够的概念来维持一个为断言执行代码生成[2]。70S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-在OCL 2.0提案中,操作oclAsType()的签名没有被一致地处理,因为该操作的返回类型被不同地指定:• 在OCL 2.0提案的第2.5.9节中,返回类型被指定为• 在6.2.1节中,返回类型是未命名类型T。这两种返回类型都没有完全正确地指定。一方面,OclType的实例是枚举文字,因此不能像预期的那样成为重新类型化的对象。另一方面,未命名的类型T在签名中没有具体的含义,因为T只与参数化类型一起出现,但实际上没有涉及这样的类型。正确的签名因此是OclAny::oclAsType(typical:OclType):OclAny。由于operationoclAsType()返回的对象可能是不同类型的,这意味着该对象是OclAny的一个实例(子类型),这就是我们对该操作的签名所能假设的但在这种情况下,另一个语义问题出现了。在OCL 2.0提案的第2.4.6节中,要求操作oclAsType()只能用于将对象重新类型化为其子类型之一,即,只允许向下铸造但另一方面,操作oclAsType()实际上在OCL2.0提案中也被用于向上转换对象,以访问超类型的覆盖属性[4,Secion2.5.8]。这个问题必须通过操作oclAsType()的OCL规范来解决。这里注 意 , 操 作 oclAsType ( ) 的 当 前 规 范 没 有 考 虑 结 果 可 能 是OclUndefined[5,Section 6.2.1]。无论最终选择两种适用的语义中的哪一种(仅向下转换或向上和向下转换),重要的是要理解,这样的后置条件必须访问元级M2。这是因为必须考虑类型一致性,这是通过元类型分类器及其操作conformsTo()在元级别M2上建模的。图2中所示的OCL约束试图提供一个OCL在当前OCL 2.0提议的上下文中,操作oclAsType(typical:OclType)的后置条件。我们在这里考虑向上和向下转换语义的更一般的情况。当只打算使用向下转换语义时,我们只需忽略第22行中的约束条件现在我们对后置条件做一个简单的解释。首先,变量selfTypes保存self对象是其实例的类型请注意,结果可能是一组枚举文字,因为UML中的对象通常可能是一个以上类型(或类)的直接实例当然,这是一个需要进一步讨论的问题:S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-711:contextOclAny::oclAsTypes(typename:OclType):OclAny2:def:selfTypes =3:OclType. allList()4:->select(t:OclType)|5:self.oclIsTypeOf(t)):Set(OclType)6:post:let7:argClassifier =8:Classifier. allpark()9:->select(c:分类器|10:c.name = type.toString())11:->any(true):分类器,12:selfClassifiers =13:Classifier. allpark()14:->select(c:分类器|15:selfTypes->exists(t:OclType|16:c.name = t.toString())17:):Set(Classifier)18:在19:if selfClassifiers20:->exists(c:分类器|21:argClassifier.conformsTo(c)22:or c.conformsTo(argClassifier))then 23:result =self and result.oclIsTypeOf(typical)24:else25:result = OclUndefined和result.oclIsTypeOf(OclVoid)26:endif图二. 使用向上和向下转换语义指定oclAsType()问题是在重新输入时是否考虑了对象的所有类型(实际的参数类型必须只符合一组类型之一),或者是否考虑了通过计算前面的OCL表达式确定的唯一类型。我们在这里采用更一般的情况,即在重新键入时考虑对象的所有VariableargClassifier保持唯一的Classier,其名称由实际参数类型指定(第7 - 11行)。请注意,格式良好性约束已经要求类化器名称可以是唯一的由他们的名字决定。此外,我们必须假设操作toString()可以应用于枚举文字。我们在这里使用该操作从枚举字面量生成String,这些枚举字面量可以特别与所引用的UML用户模型的类器名称进行比较(第10行和第16行)。变量selfClassifiers表示M1层上的一组分类器,其名称符合selfType的元素(第12 - 17行)。请注意,我们访问元层M2,因为必须选择Classifier的实例(第9然后,72S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-«电源类型»OclTypeOclAnyOclMessage«数据类型»收集{完整,重叠}(...)«数据类型»房«数据类型»OrderedSet不«数据类型»序列不这个省略号(.)indi-表示所有用户定义的M1级分类器都是OclAny«枚举»布尔«数据类型»字符串«数据类型»设置不«数据类型»袋不«枚举»OclState«数据类型»整数«枚举»OclVoid不不图三. OCL标准库类型提案对象类型的子类型或超类型。如果不是,则结果为OclUndefined(第25行)。图2所示的约束可以直接应用于OCL2.0提议相关操作的规范,如oclIsTypeOf()和oclIsKindOf(),可以用类似的方式来表达。不幸的是,必须访问两个建模级别,这在OCL 2.0中是不希望的提议因此,我们将在下一节中提出一种不同的方法,找到一种更优雅(并且符合UML)的方法来捕获建模层M1上的OCL类型。4OclType作为PowerType到目前为止,还没有一种建模OclType的方法考虑过幂类型的概念。Powertype是一个UML核心概念,它表示泛化之间的依赖关系[5,3.36节一个powertype被建模作为驻留在级别M1上的类图的一部分。基本上,powertype是一个用户定义的元元素,其实例是用户模型的类因此,powertype提供了对作为实例的专用类型的访问。图3显示了OclType作为OclAny的电源类型。这意味着OclAny的子类型是OclType的实例,例如,类型是OclType的一个实例。 因此,powertype概念非常适合在OCL标准库类型系统中将类型表示为OclTypeS. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-731:context OclAny::oclAsType(typical:OclType):OclAny2:post:ifOclType. allType()3:->select(t:OclType)|self.oclIsTypeOf(t))4:->exists(t:OclType|t y p i c a l .conformsTo(t)或t.conformsTo(typical)),则5:result=self和result.oclIsTypeOf(typename)6:其他7:result = OclUndefined和result.oclIsTypeOf(OclVoid)8:endif4.1在PowerType方法中重新键入对象我们假设操作allpark()和conformsTo(t:OclType)是为幂类型OclType定义的,类似于当前UML 1.5标准中的元级注意,我们允许对OclType本身(作为“类操作”)以及它的实例应用操作allpark(),即,OclState、OclVoid和用户定义类等类型然而,当将该操作应用于具有无限值集的类型时,例如,OCL或Real,该操作返回OclUndefined,如OCL 2.0提案[4,Section 6.2.1]中所要求的。由于操 作allpark()是 为 幂 类 型 OclType定 义 的 , 因 此 它 不 再 需 要OclAny类型,因此我们建议将其从该类型中删除。OclAny的操作oclAsType()的结果见图4。 使用Powertype方法指定oclAsType()但是仍然需要元级,例如,用于评估操作allpark()和conformsTo()的结果。但是现在所有需要访问元层的操作都定义为OclType,即,我们有明确的分工。4.2OCL标准库的其他增强功能通常,OCL 2.0建议中的图可以使用UML提供的更多标准图形模型元素。因此,作为一个案例研究,图3显示了OCL标准库类型系统的图形化表示法中的更多增强,即,• 省略号用(...)表示在UML [5,Section 6.8.1.1]中)。 它用于指示存在未在特定关系图中显示的其他子级(或子类型)。在我们的例子中,我们可以使用省略号来表示已经存在的OclAny子类型,因为OCL表达式只对给定的UML有意义74S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-使用用户定义类的模型。我们在这个省略号中添加了一个注释,以解释它表示所引用的UML用户模型的所有用户定义的类。• OclAny类型以斜体显示,表示它是一个抽象类。这同样适用于参数化类型Collection(T)。• 附加的标准约束关键字完成和重叠分类OclAny之间的泛化。注释完成意味着OclAny的所有子节点都具有已声明(无论是否显示)[5,第3.50节]。请注意,这与用于表示用户定义类的省略号并不矛盾;我们再次论证OCL表达式仅在给定的UML模型上有意义。注释重叠指示实例可以是两个或更多子对象的直接或间接实例。由于OCL类型OclVoid,所考虑的泛化是重叠的。• 预定义的OCL类型由标准的原型注释,以进一步表明它们是数据类型还是枚举。• 类型OclModelElement被省略了,因为我们认为它在当前的OCL 2.0提案中是超级复杂的• 最后,引入了参数化类OrderedSet(T),因为这种集合类型最近被添加到OCL 2.0中。只需要额外考虑未定义的值OclUndefined是否也需要是OclType的实例。 但到目前为止,我们认为没有必要这样做。5结论在本文中, 我们专注于最新的OCL 2.0提案w.r.t.对OCL类型之间类型一致性的推理操作的定义,例如,oclAsType()和oclIsTypeOf()。我们识别了操作签名和重新类型化语义之间的不一致,并提供了一个允许向上和向下转换的oclAsType()此外,我们建议使用powertype概念来对建模层M1上的OCL表达式中可访问的类型进行建模。在这方面,可以解决一些其他未决问题,例如,我们建议操作allpark()不再属于OclAny,因为将其应用于对象和数据类型值没有意义。 相反,它自然属于电源类型OclType。OCL 2.0S. Flake / Electronic Notes in Theoretical Computer Science 102(2004)63-75在基本定义中已经存在明显缺陷的标准,例如所讨论的操作。我们意识到在OCL 2.0提案中还有很多其他悬而未决的问题需要讨论,特别是w.r.t.。这两个语义定义目前既不一致也不完整。我们认为一个完整的、一致的OCL语义是非常重要的,因此我们建立在M的形式化OCL语义的Richters虽然我们关于Statecharts在OCL中的作用的研究已经基本完成[3],但我们目前关注的是OCL消息的形式化语义。确认这项工作得到了德国研究共同体在特别研究计划614引用[1] T. 巴尔河。嗨。我对OCLT型的改进感到满意。 在R。 法国人。李文,李文生,李文生。[2] A. D. Brucker和B. Wol. HOL-OCL:经验,后果和设计选择。 在UML 2002施普林格,2002年。[3] S. 佛莱克西和W。 Müller. 在ObjectConstr tra nt语言中的Sta te-Orintee表示的S e mantic s。 在第15届国际会议上,软件工程和知识工程(SEKE 2003),旧金山,美国,第142-149页。美国知识系统研究所,2003年7月。[4] A.我 不 知 道 , J 。 H ?ogstr ? m , S.John st on , D.Knox , andP.好 的 。ResponsetotheUML2. 0OCLRfP ,版本1.6 (提交者:Boldsoft 、Rational 、IONA 、AdaptiveLtd.,等人)。OMG文件ad/03-01-07,2003年1月。[5] 对象管理组。统一建模语言1.5规范。OMG文件正式/03-03-01,2003年3月。[6] M.里克特验证UML模型和OCL约束的精确方法。PhD thesis,UniversitéatBremen,Bremen,Germany,2001.
下载后可阅读完整内容,剩余1页未读,立即下载
cpongm
- 粉丝: 5
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Haskell编写的C-Minus编译器针对TM架构实现
- 水电模拟工具HydroElectric开发使用Matlab
- Vue与antd结合的后台管理系统分模块打包技术解析
- 微信小游戏开发新框架:SFramework_LayaAir
- AFO算法与GA/PSO在多式联运路径优化中的应用研究
- MapleLeaflet:Ruby中构建Leaflet.js地图的简易工具
- FontForge安装包下载指南
- 个人博客系统开发:设计、安全与管理功能解析
- SmartWiki-AmazeUI风格:自定义Markdown Wiki系统
- USB虚拟串口驱动助力刻字机高效运行
- 加拿大早期种子投资通用条款清单详解
- SSM与Layui结合的汽车租赁系统
- 探索混沌与精英引导结合的鲸鱼优化算法
- Scala教程详解:代码实例与实践操作指南
- Rails 4.0+ 资产管道集成 Handlebars.js 实例解析
- Python实现Spark计算矩阵向量的余弦相似度
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功