DIRECTORY Rope, IO, MathExpr, MathConstructors, AlgebraClasses, Structures, Ints, Vectors; VectorsImpl: CEDAR PROGRAM IMPORTS Rope, IO, MathConstructors, Structures, AlgebraClasses, Ints EXPORTS Vectors = BEGIN OPEN AC: AlgebraClasses, Vectors; SyntaxError: PUBLIC ERROR [reason: ATOM] = CODE; BadCoordinateStructure: PUBLIC ERROR [coordinateStructure: AC.Object] = CODE; TypeError: PUBLIC ERROR [message: ATOM _ $Unspecified] = CODE; Method: TYPE = AC.Method; Object: TYPE = AC.Object; MakeVectorStructure: PUBLIC AC.VectorStructureConstructor ~ { vectorStructureData: VectorStructureData _ NEW[VectorStructureDataRec _ [ row: row, coordinateStructure: coordinateStructure, dimension: dimension ] ]; method: Method _ AC.LookupMethodInStructure[$category, coordinateStructure]; category: REF AC.Category _ NARROW[method.value]; SELECT category^ FROM set => vectorStructure _ AC.MakeStructure[ name: NIL, class: vectorsClass, instanceData: vectorStructureData ]; group => vectorStructure _ AC.MakeStructure[ name: NIL, class: vectorsOverGroupClass, instanceData: vectorStructureData ]; ring, algebra => vectorStructure _ AC.MakeStructure[ name: NIL, class: vectorsOverRingClass, instanceData: vectorStructureData ]; field, divisionAlgebra => vectorStructure _ AC.MakeStructure[ name: NIL, class: vectorsOverFieldClass, instanceData: vectorStructureData ]; ENDCASE => ERROR BadCoordinateStructure[coordinateStructure]; vectorStructure.name _ ShortPrintName[vectorStructure]; IF AC.LookupStructure[vectorStructure.name] = NIL THEN AC.InstallStructure[vectorStructure]; }; PrintName: PUBLIC AC.ToRopeOp = { data: VectorStructureData _ NARROW[in.data]; shortPrintNameMethod: Method _ AC.LookupMethodInStructure[$shortPrintName, data.coordinateStructure]; RETURN[Rope.Concat[ "Vectors over ", NARROW[AC.ApplyNoLkpNoRecastRef[shortPrintNameMethod,LIST[data.coordinateStructure] ] ] ] ]; }; ShortPrintName: PUBLIC AC.ToRopeOp = { data: VectorStructureData _ NARROW[in.data]; shortPrintNameMethod: Method _ AC.LookupMethodInStructure[$shortPrintName, data.coordinateStructure]; RETURN[Rope.Cat[ "Vec(", NARROW[AC.ApplyNoLkpNoRecastRef[shortPrintNameMethod,LIST[data.coordinateStructure] ] ], ")" ] ]; }; CoordinateStructure: PUBLIC AC.UnaryOp = { data: VectorStructureData _ NARROW[arg.data]; RETURN[data.coordinateStructure]; }; Dimension: PUBLIC AC.StructureRankOp = { data: VectorStructureData _ NARROW[structure.data]; RETURN[data.dimension]; }; IsVectorStructure: PUBLIC AC.UnaryPredicate = { RETURN[ISTYPE[arg.data, VectorStructureData] ]; }; Recast: PUBLIC AC.BinaryOp = { thisVectorStructure: Object _ secondArg; thisVectorStructureData: VectorStructureData _ NARROW[thisVectorStructure.data]; thisStructureCoordinateStructure: Object _ thisVectorStructureData.coordinateStructure; thisStructureDimension: NAT _ thisVectorStructureData.dimension; canRecastMethod: Method _ AC.LookupMethodInStructure[$canRecast, thisStructureCoordinateStructure]; recastMethod: Method _ AC.LookupMethodInStructure[$recast, thisStructureCoordinateStructure]; flag: BOOL; IF AC.StructureEqual[firstArg.class, secondArg] THEN RETURN[firstArg]; -- nothing to do flag _ AC.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[firstArg.class, thisStructureCoordinateStructure] ]; IF flag THEN { recastElement: Object _ AC.ApplyNoLkpNoRecastObject[recastMethod, LIST[firstArg, thisStructureCoordinateStructure] ]; RETURN[ ImbedScalar[recastElement, thisVectorStructure] ]; }; IF AC.LookupMethodInStructure[$vectorStructure, firstArg.class]#NIL THEN { inputVectorStructure: Object _ firstArg.class; inputVectorStructureData: VectorStructureData _ NARROW[inputVectorStructure.data]; inputStructureCoordinateStructure: Object _ inputVectorStructureData.coordinateStructure; inputStructureDimension: NAT _ inputVectorStructureData.dimension; argData: VectorData _ NARROW[firstArg.data]; resultData: VectorData; IF thisStructureDimension#inputStructureDimension THEN RETURN[NIL]; flag _ AC.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[inputStructureCoordinateStructure, thisStructureCoordinateStructure] ]; IF NOT flag THEN RETURN[NIL]; -- give up resultData _ NEW[VectorDataRec[argData.dimensionPlus1 - 1] ]; FOR i:NAT IN [1..argData.dimensionPlus1) DO resultData[i] _ AC.ApplyNoLkpNoRecastObject[recastMethod, LIST[argData[i], thisStructureCoordinateStructure] ]; ENDLOOP; RETURN[ NEW[AC.ObjectRec _ [ flavor: StructureElement, class: thisVectorStructure, data: resultData ] ] ]; }; RETURN[NIL]; }; CanRecast: PUBLIC AC.BinaryPredicate = { thisVectorStructure: Object _ secondArg; thisVectorStructureData: VectorStructureData _ NARROW[thisVectorStructure.data]; thisStructureCoordinateStructure: Object _ thisVectorStructureData.coordinateStructure; thisStructureDimension: NAT _ thisVectorStructureData.dimension; canRecastMethod: Method _ AC.LookupMethodInStructure[$canRecast, thisStructureCoordinateStructure]; flag: BOOL; firstArgStructure: Object _ IF firstArg.flavor = StructureElement THEN firstArg.class ELSE IF firstArg.flavor = Structure THEN firstArg ELSE ERROR; IF AC.StructureEqual[firstArgStructure, thisVectorStructure] THEN RETURN[TRUE]; flag _ AC.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[firstArgStructure, thisStructureCoordinateStructure] ]; IF flag THEN RETURN[TRUE]; IF AC.LookupMethodInStructure[$vectorStructure, firstArgStructure]#NIL THEN { inputVectorStructure: Object _ firstArgStructure; inputVectorStructureData: VectorStructureData _ NARROW[inputVectorStructure.data]; inputStructureCoordinateStructure: Object _ inputVectorStructureData.coordinateStructure; inputStructureDimension: NAT _ inputVectorStructureData.dimension; IF thisStructureDimension#inputStructureDimension THEN RETURN[FALSE]; flag _ AC.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[inputStructureCoordinateStructure, thisStructureCoordinateStructure] ]; RETURN[flag]; }; RETURN[FALSE]; }; ToExpr: PUBLIC AC.ToExprOp = { vectorData: VectorData _ NARROW[in.data]; vectorStructureData: VectorStructureData _ NARROW[in.class.data]; size: CARDINAL _ vectorData.dimensionPlus1 - 1; outColumn: LIST OF MathExpr.EXPR _ NIL; method: Method _ AC.LookupMethodInStructure[$toExpr, vectorStructureData.coordinateStructure]; FOR j:NAT DECREASING IN [1..size] DO outColumn _ CONS[NARROW[AC.ApplyNoLkpNoRecastRef[method, LIST[vectorData[j]] ]] , outColumn]; ENDLOOP; out _ MathConstructors.MakeVector[size, outColumn, vectorStructureData.row]; -- row (not column) vector }; LegalFirstChar: PUBLIC AC.LegalFirstCharOp = { SELECT char FROM '[ => RETURN[TRUE]; ENDCASE; RETURN[FALSE]; }; Read: PUBLIC AC.ReadOp ~ { structureData: VectorStructureData _ NARROW[structure.data]; coordinateStructure: AC.Object _ structureData.coordinateStructure; readMethod: AC.Method _ AC.LookupMethodInStructure[$read, coordinateStructure]; puncChar: CHAR; nextElement: AC.Object; length: NAT _ 0; list, listTail: LIST OF AC.Object _ NIL; outData: VectorData; []_ in.SkipWhitespace[]; puncChar _ in.GetChar[]; []_ in.SkipWhitespace[]; IF puncChar # '[ THEN ERROR SyntaxError[$LeftParenExpected]; []_ in.SkipWhitespace[]; puncChar _ in.PeekChar[]; IF puncChar = '] THEN puncChar _ in.GetChar[]; WHILE puncChar # '] DO nextElement _ AC.ApplyReadMethod[readMethod, in, coordinateStructure]; length _ length + 1; []_ in.SkipWhitespace[]; IF list=NIL THEN list _ listTail _LIST[nextElement] ELSE { listTail.rest _ LIST[nextElement]; listTail _ listTail.rest }; puncChar _ in.GetChar[]; []_ in.SkipWhitespace[]; IF puncChar # '] THEN IF puncChar # ', THEN ERROR SyntaxError[$CommaExpected]; ENDLOOP; outData _ NEW[VectorDataRec[length] ]; FOR i:NAT IN [1..length] DO outData[i] _ list.first; list _ list.rest; ENDLOOP; out _ NEW[AC.ObjectRec _ [flavor: StructureElement, class: structure, data: outData] ]; }; FromRope: PUBLIC AC.FromRopeOp ~ { out _ Read[IO.RIS[in], structure]; }; ToRope: PUBLIC AC.ToRopeOp ~ { vectorStructureData: VectorStructureData _ NARROW[in.class.data]; coordinateStructure: AC.Object _ vectorStructureData.coordinateStructure; toRopeMethod: AC.Method _ AC.LookupMethodInStructure[$toRope, coordinateStructure]; inData: VectorData _ NARROW[in.data]; out _ "[ "; FOR i:NAT IN [1..inData.dimensionPlus1) DO out _ Rope.Concat[ out, NARROW[AC.ApplyNoLkpNoRecastRef[toRopeMethod, LIST[inData[i] ] ] ] ]; IF i < inData.dimensionPlus1-1 THEN out _ Rope.Concat[out,", "]; ENDLOOP; out _ Rope.Concat[ out, " ]" ]; }; Write: PUBLIC AC.WriteOp ~ { stream.PutRope[ ToRope[in] ] }; ImbedScalar: PUBLIC AC.UnaryImbedOp ~ { dimension: NAT _ Dimension[structure]; resultData: VectorData _ NEW[VectorDataRec[dimension] ]; FOR i:NAT IN [1..dimension] DO resultData[i] _ in; ENDLOOP; RETURN[ NEW[AC.ObjectRec _ [ flavor: StructureElement, class: structure, data: resultData ] ] ]; }; MakeVector: PUBLIC AC.ListImbedOp ~ { structureData: VectorStructureData _ NARROW[structure.data]; coordinateStructure: AC.Object _ structureData.coordinateStructure; dimension: NAT _ structureData.dimension; recastMethod: Method _ AC.LookupMethodInStructure[$recast, coordinateStructure]; length: NAT _ 0; ptr: LIST OF AC.Object _ data; outData: VectorData; WHILE ptr#NIL DO length _ length + 1; ptr _ ptr.rest ENDLOOP; IF length#dimension THEN ERROR TypeError[$BadDimension]; outData _ NEW[VectorDataRec[dimension] ]; FOR i:NAT IN [1..dimension] DO outData[i] _ AC.ApplyNoLkpNoRecastObject[recastMethod, LIST[data.first, coordinateStructure] ]; IF outData[i] = NIL THEN TypeError[]; data _ data.rest; ENDLOOP; out _ NEW[AC.ObjectRec _ [flavor: StructureElement, class: structure, data: outData] ]; }; Coordinate: PUBLIC AC.BinaryOp ~ { firstData: VectorData _ NARROW[firstArg.data]; index: INT _ Ints.ToINT[secondArg]; IF index<1 OR firstData.dimensionPlus1-1J˜Jšœœœ˜Jšœœœ˜—šœ™šΟnœœœ˜=šœ+œ˜IK˜ Kšœ)˜)K˜Kšœ˜—Kšœœ9˜LKšœ œœ œ˜1šœ ˜šœœ˜*Kšœœ˜ Kšœ˜Kšœ!˜!Kšœ˜—šœœ˜,Kšœœ˜ Kšœ˜Kšœ!˜!Kšœ˜—šœ#œ˜4Kšœœ˜ Kšœ˜Kšœ!˜!Kšœ˜—šœ,œ˜=Kšœœ˜ Kšœ˜Kšœ!˜!Kšœ˜—Kšœœ-˜=—Kšœ7˜7Kš œœ)œœœ#˜\K˜—šž œ œ ˜!Jšœœ ˜,KšœœD˜ešœ ˜Jšœ˜Jšœœ,œ˜WJšœ˜—J˜J˜—šžœ œ ˜&Jšœœ ˜,KšœœD˜ešœ ˜J˜Jšœœ,œ˜XJšœ˜Jšœ˜—J˜J˜—šžœ œ ˜*Jšœœ ˜-Jšœ˜!J˜J˜—šž œ œ˜(Jšœœ˜3Jšœ˜J˜J˜—šžœœœ˜/Jšœœ"˜/J˜J˜——šœ™šžœ œ ˜Jšœ+™+J˜(Jšœ/œ˜PJšœW˜WJšœ@˜@KšœœG˜cKšœœD˜]Jšœœ˜ J˜Jš œœ+œœ Οc˜WJ˜Jšœ@™@Jšœœ(œ5˜jšœœ˜Jšœœ(œ/˜uJšœ4˜:Jšœ˜J˜—Jšœ§™§šœœ;œœ˜JJšœ.˜.Jšœ0œ˜RJšœY˜YJšœB˜BJšœœ˜,Jšœ˜Jšœ0œœœ˜CJšœœ(œH˜}Jš œœœœœŸ ˜(Jšœ œ-˜=šœœœ˜+Jšœœ(œ1˜oJšœ˜—šœœœ˜K˜Kšœ˜Kšœ˜Kšœ˜—K˜—K˜K™ Kšœœ˜ K˜J˜—šž œ œ˜(JšœG™GJ˜(Jšœ/œ˜PJšœW˜WJšœ@˜@KšœœG˜cJšœœ˜ Jšœœ$œœœœ œœ˜“Jš œœ8œœœ˜OJ˜Jšœœ(œ8˜mJšœœœœ˜J˜šœœ>œœ˜MJšœ1˜1Jšœ0œ˜RJšœY˜YJšœB˜BJšœ0œœœ˜EJšœœ(œH˜}Jšœ˜ K˜—Kšœœ˜K˜J˜—šžœ œ ˜Jšœœ ˜)Jšœ+œ˜AJšœœ!˜/Jš œ œœ œœ˜'KšœœK˜^š œœ œœ ˜$Jš œ œœœœ ˜]Kšœ˜—JšœNŸ˜hJšœ˜—šžœ œ˜.šœ˜Kšœœœ˜Kšœ˜—Kšœœ˜J˜J˜—šžœœœ ˜Jšœ%œ˜™>Jšœ(™(Jšœ%œ˜Jšœ>˜DJ˜J˜—šžœ œ ˜&J™(Jšœœ˜0Jšœ+œ˜HJšœF˜FJšœ œ!˜/Kšœœ8˜RJšœ˜Jšœ œ˜,šœœœ˜Jšœœ)œŸ˜]Jšœ˜—Jšœ œœT˜cK˜J™—šžœ œ ™*J™—šžœ œ ™'J™—šžœ œ ™'J™—Jšžœ œ ™(—šž ™ šžœœœ˜$Jšœœ˜1Jšœœ˜3Jšœ+œ˜GKšœ!œN˜qJšœ<œœœ˜Qšœœœ"˜1Jšœœœ0œ'œœœ˜wJšœ˜—Jšœœ˜ J˜——šž ™ šžœœœ˜.Kšœ8žœžœ}™ΜJšœœ˜/Kšœœ ˜#Jšœ)œ œ˜9Jšœ œ˜+Jšœœ˜5šœœœ˜Jšœ œ"œ˜HJšœ œœ+˜BJšœ˜—Jš œœœœ Ÿ˜PJšœI˜Išœœœ˜K˜Kšœ˜Kšœ ˜ Kšœ˜—K˜K˜—šžœœœ˜0Kšœ€žœžœ¨™ΑJšœœ˜.Jšœœ˜0Kšœœ ˜"Jšœ)œ œ˜9Jšœ œ˜+JšœB˜BJšœœ˜5šœœœ˜Jšœ œ3œ"Ÿ ˜vJšœ œœ+˜BJšœ˜—Jš œœœœ Ÿ˜PJšœI˜Išœœœ˜K˜Kšœ˜Kšœ ˜ Kšœ˜—K˜——™šžœœœ˜0JšœœŸ'˜GJ˜J˜—šžœœœ˜7Jšœ/œ ˜@JšœJ˜JJšœœŸ'˜QJ˜—šžœœœ˜7Jšœ/œ ˜@JšœJ˜JJšœœŸ'˜QJ˜—šžœœœ™:Jšœ/œ ™@JšœJ™JJšœœ)Ÿ'™\J™——™ š œœ œœœ˜AK˜—šœœ œ2œ˜\Kšœ™K˜—šœœ œ:œ˜cKšœ™K˜—šœœ œ:œ˜dKšœ™—J˜Jš œœœœœœœ˜ZJš œœœœœœœ˜^Jš œœœœœœœ˜\Jš œœœœœœœ˜^Jš œ$œœœœœœ˜jJš œ œœœœ˜YJš œ œœœœ˜YJš œœœœœœ˜xJš œœœœœœ ˜_Jš œœœœœœ˜vJšœœœœœœœœžœ ˜“Jš œœœœœ%œ˜ˆJš œœœœœœ ˜VJš œœœœœœ˜iJš œœœœœœ ˜`Jš œœœœœ œœ ˜]Jš œœœœœœ˜wJš œœœœœœ ˜jJš œœœœœœœ5˜“Jš œœœœœœ ˜\Jš œœœœœœ ˜YJšœœœœœœœœ&˜‰Jšœœœœœœœœ+˜”Jšœœœœœœœœ-˜œJš œœœœœœœ?˜€Jšœœœœœœœœ)˜žJš œ"œœœœ%œŸ+˜­Jš œ#œœœœ'œŸ+˜²J˜Jš œ$œ(œœœ4œ˜«J˜J˜Jšœ>˜@JšœI˜KJšœI˜KJšœG˜IJšœ7˜9Jšœ=˜?Jšœ7˜9JšœG˜IJšœ3˜5Jšœ;˜=Jšœ7˜9Jšœ5˜7Jšœ7˜9Jšœ?˜AJšœ9˜;JšœD˜FJšœF˜HJ˜JšœI˜KJšœ<˜>Jšœ:˜