Element Conversion and IO
PowerSetRecast:
PUBLIC AlgebraClasses.BinaryOp = {
Args are a StructureElement and a Structure
thisSetStructure: Object ← secondArg;
thisSetStructureData: PowerSetStructureData ← NARROW[thisSetStructure.data];
thisStructureUniverse: Object ← thisSetStructureData.universe;
canRecastMethod: Method ← AlgebraClasses.LookupMethodInStructure[$canRecast, thisStructureUniverse];
recastMethod: Method ← AlgebraClasses.LookupMethodInStructure[$recast, thisStructureUniverse];
flag: BOOL;
IF AlgebraClasses.StructureEqual[firstArg.class, secondArg] THEN RETURN[firstArg]; -- nothing to do
See if can recast firstArg as an element of thisStructureUniverse
flag ← AlgebraClasses.ApplyPredNoLkpNoRecast[canRecastMethod, LIST[firstArg.class, thisStructureUniverse] ];
IF flag
THEN {
recastElement: Object ← AlgebraClasses.ApplyNoLkpNoRecastObject[recastMethod, LIST[firstArg, thisStructureUniverse] ];
RETURN[ MakeSet[LIST[recastElement], thisSetStructure] ];
};
If firstArg is an element of a PowerSetStructure, see if can recast that Structure's universe into thisStructureUniverse; if so, recast (each element of) firstArg.
IF AlgebraClasses.LookupMethodInStructure[$powerSetStructure, firstArg.class]#
NIL
THEN {
inputSetStructure: Object ← firstArg.class;
inputSetStructureData: PowerSetStructureData ← NARROW[inputSetStructure.data];
inputStructureUniverse: Object ← inputSetStructureData.universe;
argData: SetData ← NARROW[firstArg.data];
resultData, resultDataPtr: SetData ← NIL;
flag ← AlgebraClasses.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[inputStructureUniverse, thisStructureUniverse] ];
IF NOT flag THEN RETURN[NIL]; -- give up
WHILE argData#
NIL
DO
IF resultData =
NIL
THEN
resultData ← resultDataPtr ← LIST[AlgebraClasses.ApplyNoLkpNoRecastObject[recastMethod, LIST[argData.first, thisStructureUniverse] ] ]
ELSE
resultDataPtr ← resultDataPtr.rest ← LIST[AlgebraClasses.ApplyNoLkpNoRecastObject[recastMethod, LIST[argData.first, thisStructureUniverse] ] ];
argData ← argData.rest
ENDLOOP;
RETURN[
NEW[AlgebraClasses.ObjectRec ← [
flavor: StructureElement,
class: thisSetStructure,
data: resultData
] ] ];
};
Can't do it
RETURN[NIL];
};
PowerSetCanRecast:
PUBLIC AlgebraClasses.BinaryPredicate = {
Args are either [Structure, Structure] or [StructureElement, Structure]
thisSetStructure: Object ← secondArg;
thisSetStructureData: PowerSetStructureData ← NARROW[thisSetStructure.data];
thisStructureUniverse: Object ← thisSetStructureData.universe;
canRecastMethod: Method ← AlgebraClasses.LookupMethodInStructure[$canRecast, thisStructureUniverse];
flag: BOOL;
firstArgStructure: Object ← IF firstArg.flavor = StructureElement THEN firstArg.class ELSE IF firstArg.flavor = Structure THEN firstArg ELSE ERROR;
IF AlgebraClasses.StructureEqual[firstArgStructure, thisSetStructure] THEN RETURN[TRUE];
flag ← AlgebraClasses.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[firstArgStructure, thisStructureUniverse] ];
IF flag THEN RETURN[TRUE];
IF AlgebraClasses.LookupMethodInStructure[$powerSetStructure, firstArgStructure]#
NIL
THEN {
inputSetStructure: Object ← firstArgStructure;
inputSetStructureData: PowerSetStructureData ← NARROW[inputSetStructure.data];
inputStructureUniverse: Object ← inputSetStructureData.universe;
flag ← AlgebraClasses.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[inputStructureUniverse, thisStructureUniverse] ];
RETURN[flag];
};
RETURN[FALSE];
};
PowerSetToExpr:
PUBLIC AlgebraClasses.ToExprOp = {
setData: SetData ← NARROW[in.data];
setStructureData: PowerSetStructureData ← NARROW[in.class.data];
cardinality: NAT ← 0;
outColumn, outColumnPtr: LIST OF MathExpr.EXPR ← NIL;
method: Method ← AlgebraClasses.LookupMethodInStructure[$toExpr, setStructureData.universe];
WHILE setData #
NIL
DO
cardinality ← cardinality + 1;
IF outColumn =
NIL
THEN
outColumn ← outColumnPtr ← LIST[NARROW[AlgebraClasses.ApplyNoLkpNoRecastRef[method, LIST[setData.first] ] ] ]
ELSE
outColumnPtr ← outColumnPtr.rest ← LIST[NARROW[AlgebraClasses.ApplyNoLkpNoRecastRef[method, LIST[setData.first] ] ] ];
setData ← setData.rest;
ENDLOOP;
out ← MathConstructors.MakeSet[cardinality, outColumn, TRUE]; -- row (not column) set
};
PowerSetLegalFirstChar:
PUBLIC AlgebraClasses.LegalFirstCharOp = {
SELECT char
FROM
'{=> RETURN[TRUE];
ENDCASE;
RETURN[FALSE];
};
PowerSetRead:
PUBLIC AlgebraClasses.ReadOp ~ {
structureData: PowerSetStructureData ← NARROW[structure.data];
universe: AlgebraClasses.Object ← structureData.universe;
readMethod: AlgebraClasses.Method ← AlgebraClasses.LookupMethodInStructure[$read, universe];
puncChar: CHAR;
nextElement: AlgebraClasses.Object;
length: NAT ← 0;
ReadFail: PUBLIC ERROR [subclass: ATOM ← $Unspecified] = CODE;
list, listTail: SetData ← NIL;
[]← in.SkipWhitespace[];
puncChar ← in.GetChar[];
[]← in.SkipWhitespace[];
IF puncChar # '{ THEN ReadFail[$LeftCurlyBracketExpected];
[]← in.SkipWhitespace[];
puncChar ← in.PeekChar[];
IF puncChar = '} THEN puncChar ← in.GetChar[];
WHILE puncChar # '}
DO
nextElement ← AlgebraClasses.ApplyReadMethod[readMethod, in, universe];
length ← length + 1;
[]← in.SkipWhitespace[];
IF list=
NIL
THEN
list ← listTail ←LIST[nextElement]
ELSE
listTail ← listTail.rest ← LIST[nextElement];
puncChar ← in.GetChar[];
[]← in.SkipWhitespace[];
IF puncChar # '}
THEN
IF puncChar # ', THEN ReadFail[$CommaExpected];
ENDLOOP;
out ← NEW[AlgebraClasses.ObjectRec ← [flavor: StructureElement, class: structure, data: list] ];
};
PowerSetFromRope:
PUBLIC AlgebraClasses.FromRopeOp ~ {
out ← PowerSetRead[IO.RIS[in], structure];
};
PowerSetToRope:
PUBLIC AlgebraClasses.ToRopeOp ~ {
setStructureData: PowerSetStructureData ← NARROW[in.class.data];
universe: AlgebraClasses.Object ← setStructureData.universe;
toRopeMethod: AlgebraClasses.Method ← AlgebraClasses.LookupMethodInStructure[$toRope, universe];
inData: SetData ← NARROW[in.data];
out ← "{ ";
WHILE inData#
NIL
DO
out ← Rope.Concat[out, NARROW[AlgebraClasses.ApplyNoLkpNoRecastRef[toRopeMethod, LIST[inData.first] ] ] ];
IF inData.rest#NIL THEN out ← Rope.Concat[out,", "];
inData ← inData.rest;
ENDLOOP;
out ← Rope.Concat[ out, " }" ];
};
PowerSetWrite:
PUBLIC AlgebraClasses.WriteOp ~ {
stream.PutRope[ PowerSetToRope[in] ]
};
Set Operations
Cardinality:
PUBLIC AlgebraClasses.ElementRankOp ~ {
ptr: SetData ← NARROW[arg.data];
length: CARDINAL ← 0;
WHILE ptr#NIL DO length ← length + 1; ptr ← ptr.rest ENDLOOP;
RETURN[length];
};
Equal:
PUBLIC AlgebraClasses.BinaryPredicate ~ {
RETURN[ IsSubset[firstArg, secondArg] AND IsSubset[secondArg, firstArg] ];
};
Union:
PUBLIC AlgebraClasses.BinaryOp ~ {
firstSetData: SetData ← NARROW[firstArg.data];
secondSetData: SetData ← NARROW[secondArg.data];
firstStructureData: PowerSetStructureData ← NARROW[firstArg.class.data];
secondStructureData: PowerSetStructureData ← NARROW[firstArg.class.data];
firstUniverse: Object ← firstStructureData.universe;
secondUniverse: Object ← firstStructureData.universe;
resultData: SetData ← secondSetData;
IF NOT AlgebraClasses.StructureEqual[firstUniverse, secondUniverse] THEN ERROR; -- if args are being recast, we don't need this check, but leave in anyway.
WHILE firstSetData#
NIL
DO
IF NOT IsElement[firstSetData.first, secondArg] THEN resultData ← CONS[firstSetData.first, resultData];
firstSetData ← firstSetData.rest;
ENDLOOP;
RETURN[MakeSet[resultData, firstArg.class] ];
};
Intersection:
PUBLIC AlgebraClasses.BinaryOp ~ {
firstSetData: SetData ← NARROW[firstArg.data];
secondSetData: SetData ← NARROW[secondArg.data];
firstStructureData: PowerSetStructureData ← NARROW[firstArg.class.data];
secondStructureData: PowerSetStructureData ← NARROW[firstArg.class.data];
firstUniverse: Object ← firstStructureData.universe;
secondUniverse: Object ← firstStructureData.universe;
resultData: SetData ← NIL;
IF NOT AlgebraClasses.StructureEqual[firstUniverse, secondUniverse] THEN ERROR; -- if args are being recast, we don't need this check, but leave in anyway.
WHILE firstSetData#
NIL
DO
IF IsElement[firstSetData.first, secondArg] THEN resultData ← CONS[firstSetData.first, resultData];
firstSetData ← firstSetData.rest;
ENDLOOP;
RETURN[MakeSet[resultData, firstArg.class] ];
};
Difference:
PUBLIC AlgebraClasses.BinaryOp ~ {
firstSetData: SetData ← NARROW[firstArg.data];
secondSetData: SetData ← NARROW[secondArg.data];
firstStructureData: PowerSetStructureData ← NARROW[firstArg.class.data];
secondStructureData: PowerSetStructureData ← NARROW[firstArg.class.data];
firstUniverse: Object ← firstStructureData.universe;
secondUniverse: Object ← firstStructureData.universe;
resultData: SetData ← NIL;
IF NOT AlgebraClasses.StructureEqual[firstUniverse, secondUniverse] THEN ERROR; -- if args are being recast, we don't need this check, but leave in anyway.
WHILE firstSetData#
NIL
DO
IF NOT IsElement[firstSetData.first, secondArg] THEN resultData ← CONS[firstSetData.first, resultData];
firstSetData ← firstSetData.rest;
ENDLOOP;
RETURN[MakeSet[resultData, firstArg.class] ];
};
MapUnaryElementOp: PUBLIC AlgebraClasses.BinaryMixedOp ~ {
firstArg is a Set, secondArg is REF to UnaryOp on its universe
seqData: SetData ← NARROW[firstArg.data];
refOp: REF AlgebraClasses.UnaryOp ← NARROW[secondArg];
newUniverse, newSeqStructure: AlgebraClasses.Object ← NIL;
newData: SetData ← NEW[SetDataRec[seqData.lengthPlus1-1] ];
FOR i:INT IN [1..seqData.lengthPlus1) DO
newData[i] ← refOp^[seqData[i]];
IF newData[i]# NIL THEN newUniverse ← newData[i].class;
ENDLOOP;
IF newUniverse = NIL THEN RETURN[NIL];
newSeqStructure ← MakeSetStructure[newUniverse];
RETURN[ NEW[AlgebraClasses.ObjectRec ← [
flavor: StructureElement,
class: newSeqStructure,
data: newData
] ] ];
};
Start Code
powerSetClass: AlgebraClasses.Object ← AlgebraClasses.MakeClass["PowerSetClass", NIL, NIL];
singleSetClass: AlgebraClasses.Object ← AlgebraClasses.MakeClass["SingleSetClass", NIL, NIL];
setCategoryMethod: Method ← AlgebraClasses.MakeMethod[Value, FALSE, NEW[AlgebraClasses.Category ← set], NIL, NIL];
powerSetStructureMethod: Method ← AlgebraClasses.MakeMethod[Value, FALSE, NIL, NIL, "powerSetStructure"];
universeMethod: Method ← AlgebraClasses.MakeMethod[UnaryOp, FALSE, NEW[AlgebraClasses.UnaryOp ← Universe], NIL, "universe"];
underlyingSetMethod: Method ← AlgebraClasses.MakeMethod[UnaryOp, FALSE, NEW[AlgebraClasses.UnaryOp ← UnderlyingSet], NIL, "underlyingSet"];
shortPrintNameMethod: Method ← AlgebraClasses.MakeMethod[ToRopeOp, FALSE, NEW[AlgebraClasses.ToRopeOp ← PowerSetShortPrintName], NIL, "shortPrintName"];
recastMethod: Method ← AlgebraClasses.MakeMethod[BinaryOp, TRUE, NEW[AlgebraClasses.BinaryOp ← PowerSetRecast], NIL, "recast"];
canRecastMethod: Method ← AlgebraClasses.MakeMethod[BinaryPredicate, TRUE, NEW[AlgebraClasses.BinaryPredicate ← PowerSetCanRecast], NIL, "canRecast"];
toExprMethod: Method ← AlgebraClasses.MakeMethod[ToExprOp, FALSE, NEW[AlgebraClasses.ToExprOp ← PowerSetToExpr], NEW[AlgebraClasses.UnaryToListOp ← AlgebraClasses.DefaultDesiredArgStructures], "toExpr"];
legalFirstCharMethod: Method ← AlgebraClasses.MakeMethod[LegalFirstCharOp, FALSE, NEW[AlgebraClasses.LegalFirstCharOp ← PowerSetLegalFirstChar], NIL, "legalFirstChar"];
readMethod: Method ← AlgebraClasses.MakeMethod[ReadOp, FALSE, NEW[AlgebraClasses.ReadOp ← PowerSetRead], NIL, "read"];
fromRopeMethod: Method ← AlgebraClasses.MakeMethod[FromRopeOp, TRUE, NEW[AlgebraClasses.FromRopeOp ← PowerSetFromRope], NIL, "fromRope"];
toRopeMethod: Method ← AlgebraClasses.MakeMethod[ToRopeOp, FALSE, NEW[AlgebraClasses.ToRopeOp ← PowerSetToRope], NIL, "toRope"];
parenMethod: Method ← AlgebraClasses.MakeMethod[UnaryOp, FALSE, NEW[AlgebraClasses.UnaryOp ← AlgebraClasses.Copy], NIL, "paren"];
setMethod: Method ← AlgebraClasses.MakeMethod[ListImbedOp, FALSE, NEW[AlgebraClasses.ListImbedOp ← MakeSet], NIL, "set"];
elementOfMethod: Method ← AlgebraClasses.MakeMethod[BinaryPredicate, TRUE, NEW[AlgebraClasses.BinaryPredicate ← IsElement], NEW[AlgebraClasses.UnaryToListOp ← IsElDesiredArgStructures], "elementOf"];
subsetMethod: Method ← AlgebraClasses.MakeMethod[BinaryPredicate, TRUE, NEW[AlgebraClasses.BinaryPredicate ← IsSubset], NEW[AlgebraClasses.UnaryToListOp ← AlgebraClasses.DefaultDesiredArgStructures], "subset"];
cardinalityMethod: Method ← AlgebraClasses.MakeMethod[ElementRankOp, TRUE, NEW[AlgebraClasses.ElementRankOp ← Cardinality], NEW[AlgebraClasses.UnaryToListOp ← AlgebraClasses.DefaultDesiredArgStructures], "cardinality"];
equalMethod: Method ← AlgebraClasses.MakeMethod[BinaryPredicate, TRUE, NEW[AlgebraClasses.BinaryPredicate ← Equal], NEW[AlgebraClasses.UnaryToListOp ← AlgebraClasses.DefaultDesiredArgStructures], "equals"];
unionMethod: Method ← AlgebraClasses.MakeMethod[BinaryOp, TRUE, NEW[AlgebraClasses.BinaryOp ← Union], NIL, "union"];
intersectionMethod: Method ← AlgebraClasses.MakeMethod[BinaryOp, TRUE, NEW[AlgebraClasses.BinaryOp ← Intersection], NIL, "intersection"];
differenceMethod: Method ← AlgebraClasses.MakeMethod[BinaryOp, TRUE, NEW[AlgebraClasses.BinaryOp ← Difference], NIL, "difference"];
makePowerSetStructureMethod: Method ← AlgebraClasses.MakeMethod[SequenceStructureConstructor, FALSE, NEW[AlgebraClasses.SequenceStructureConstructor ← MakePowerSetStructure], NIL, "makePowerSetStructure"];
AlgebraClasses.AddMethodToClass[$category, setCategoryMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$powerSetStructure, powerSetStructureMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$universe, universeMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$shortPrintName, shortPrintNameMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$recast, recastMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$canRecast, canRecastMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$toExpr, toExprMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$legalFirstChar, legalFirstCharMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$read, readMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$fromRope, fromRopeMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$toRope, toRopeMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$paren, parenMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$set, setMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$elementOf, elementOfMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$subset, subsetMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$cardinality, cardinalityMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$eqFormula, equalMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$union, unionMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$intersect, intersectionMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$difference, differenceMethod, powerSetClass];
AlgebraClasses.AddMethodToClass[$makePowerSetStructure, makePowerSetStructureMethod, Structures.StructuresClass];