SequencesImpl.mesa
Last Edited by: Arnon, July 19, 1985 2:54:46 pm PDT
DIRECTORY
Rope,
IO,
MathExpr,
MathConstructors,
AlgebraClasses,
Structures,
Ints,
Sequences;
SequencesImpl: CEDAR PROGRAM
IMPORTS Rope, IO, MathConstructors, Structures, AlgebraClasses, Ints
EXPORTS Sequences =
BEGIN OPEN AC: AlgebraClasses, Sequences;
Errors and Types
SyntaxError: PUBLIC ERROR [reason: ATOM] = CODE;
BadElementStructure: PUBLIC ERROR [elementStructure: AC.Object] = CODE;
TypeError: PUBLIC ERROR [message: ATOM ← $Unspecified] = CODE;
Method: TYPE = AC.Method;
Object: TYPE = AC.Object;
Sequence Structure Ops
MakeSequenceStructure: PUBLIC AC.SequenceStructureConstructor ~ {
sequenceStructureData: SequenceStructureData ← NEW[SequenceStructureDataRec ← [
row: row,
elementStructure: elementStructure
] ];
sequenceStructure ← AC.MakeStructure[
name: NIL,
class: sequencesClass,
instanceData: sequenceStructureData
];
sequenceStructure.name ← ShortPrintName[sequenceStructure];
IF AC.LookupStructure[sequenceStructure.name] = NIL THEN AC.InstallStructure[sequenceStructure];
RETURN[sequenceStructure];
};
PrintName: PUBLIC AC.ToRopeOp = {
data: SequenceStructureData ← NARROW[in.data];
shortPrintNameMethod: Method ← AC.LookupMethodInStructure[$shortPrintName, data.elementStructure];
RETURN[Rope.Concat[
"Sequences over ",
NARROW[AC.ApplyNoLkpNoRecastRef[shortPrintNameMethod,LIST[data.elementStructure] ] ]
] ];
};
ShortPrintName: PUBLIC AC.ToRopeOp = {
data: SequenceStructureData ← NARROW[in.data];
shortPrintNameMethod: Method ← AC.LookupMethodInStructure[$shortPrintName, data.elementStructure];
RETURN[Rope.Cat[
"Seq(",
NARROW[AC.ApplyNoLkpNoRecastRef[shortPrintNameMethod,LIST[data.elementStructure] ] ],
")"
] ];
};
Conversion and IO
Recast: PUBLIC AC.BinaryOp = {
Args are a StructureElement and a Structure
thisSequenceStructure: Object ← secondArg;
thisSequenceStructureData: SequenceStructureData ← NARROW[thisSequenceStructure.data];
thisStructureElementStructure: Object ← thisSequenceStructureData.elementStructure;
canRecastMethod: Method ← AC.LookupMethodInStructure[$canRecast, thisStructureElementStructure];
recastMethod: Method ← AC.LookupMethodInStructure[$recast, thisStructureElementStructure];
flag: BOOL;
IF AC.StructureEqual[firstArg.class, secondArg] THEN RETURN[firstArg]; -- nothing to do
See if can recast firstArg into thisStructureElementStructure
flag ← AC.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[firstArg.class, thisStructureElementStructure] ];
IF flag THEN {
recastElement: Object ← AC.ApplyNoLkpNoRecastObject[recastMethod, LIST[firstArg, thisStructureElementStructure] ];
RETURN[ MakeSequence[LIST[recastElement], thisSequenceStructure] ];
};
If firstArg is a Sequence, see if can recast its elementStructure into thisStructureElementStructure; if so, recast all its elements.
IF AC.LookupMethodInStructure[$sequenceStructure, firstArg.class]#NIL THEN {
inputSequenceStructure: Object ← firstArg.class;
inputSequenceStructureData: SequenceStructureData ← NARROW[inputSequenceStructure.data];
inputStructureElementStructure: Object ← inputSequenceStructureData.elementStructure;
argData: SequenceData ← NARROW[firstArg.data];
resultData: SequenceData;
flag ← AC.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[inputStructureElementStructure, thisStructureElementStructure] ];
IF NOT flag THEN RETURN[NIL]; -- give up
resultData ← NEW[SequenceDataRec[argData.lengthPlus1 - 1] ];
FOR i:NAT IN [1..argData.lengthPlus1) DO
resultData[i] ← AC.ApplyNoLkpNoRecastObject[recastMethod, LIST[argData[i], thisStructureElementStructure] ];
ENDLOOP;
RETURN[ NEW[AC.ObjectRec ← [
flavor: StructureElement,
class: thisSequenceStructure,
data: resultData
] ] ];
};
Can't do it
RETURN[NIL];
};
CanRecast: PUBLIC AC.BinaryPredicate = {
Args are either [Structure, Structure] or [StructureElement, Structure]
thisSequenceStructure: Object ← secondArg;
thisSequenceStructureData: SequenceStructureData ← NARROW[thisSequenceStructure.data];
thisStructureElementStructure: Object ← thisSequenceStructureData.elementStructure;
canRecastMethod: Method ← AC.LookupMethodInStructure[$canRecast, thisStructureElementStructure];
flag: BOOL;
firstArgStructure: Object ← IF firstArg.flavor = StructureElement THEN firstArg.class ELSE IF firstArg.flavor = Structure THEN firstArg ELSE ERROR;
IF AC.StructureEqual[firstArgStructure, thisSequenceStructure] THEN RETURN[TRUE];
flag ← AC.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[firstArgStructure, thisStructureElementStructure] ];
IF flag THEN RETURN[TRUE];
IF AC.LookupMethodInStructure[$sequenceStructure, firstArgStructure]#NIL THEN {
inputSequenceStructure: Object ← firstArgStructure;
inputSequenceStructureData: SequenceStructureData ← NARROW[inputSequenceStructure.data];
inputStructureElementStructure: Object ← inputSequenceStructureData.elementStructure;
flag ← AC.ApplyPredNoLkpNoRecast[canRecastMethod,LIST[inputStructureElementStructure, thisStructureElementStructure] ];
RETURN[flag];
};
RETURN[FALSE];
};
ToExpr: PUBLIC AC.ToExprOp = {
sequenceData: SequenceData ← NARROW[in.data];
sequenceStructureData: SequenceStructureData ← NARROW[in.class.data];
size: CARDINAL ← sequenceData.lengthPlus1 - 1;
outColumn: LIST OF MathExpr.EXPRNIL;
method: Method ← AC.LookupMethodInStructure[$toExpr, sequenceStructureData.elementStructure];
FOR j:NAT DECREASING IN [1..size] DO
outColumn ← CONS[NARROW[AC.ApplyNoLkpNoRecastRef[method, LIST[sequenceData[j]] ]] , outColumn];
ENDLOOP;
out ← MathConstructors.MakeSequence[size, outColumn, sequenceStructureData.row]; -- row (not column) sequence
};
LegalFirstChar: PUBLIC AC.LegalFirstCharOp = {
SELECT char FROM
'< => RETURN[TRUE];
ENDCASE;
RETURN[FALSE];
};
Read: PUBLIC AC.ReadOp ~ {
structureData: SequenceStructureData ← NARROW[structure.data];
elementStructure: AC.Object ← structureData.elementStructure;
readMethod: AC.Method ← AC.LookupMethodInStructure[$read, elementStructure];
puncChar: CHAR;
nextElement: AC.Object;
length: NAT ← 0;
ReadFail: PUBLIC ERROR [subclass: ATOM ← $Unspecified] = CODE;
list, listTail: LIST OF AC.Object ← NIL;
outData: SequenceData;
[]← in.SkipWhitespace[];
puncChar ← in.GetChar[];
[]← in.SkipWhitespace[];
IF puncChar # '< THEN ReadFail[$LeftParenExpected];
[]← in.SkipWhitespace[];
puncChar ← in.PeekChar[];
IF puncChar = '> THEN puncChar ← in.GetChar[];
WHILE puncChar # '> DO
nextElement ← AC.ApplyReadMethod[readMethod, in, elementStructure];
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 ReadFail[$CommaExpected];
ENDLOOP;
outData ← NEW[SequenceDataRec[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 ~ {
sequenceStructureData: SequenceStructureData ← NARROW[in.class.data];
elementStructure: AC.Object ← sequenceStructureData.elementStructure;
toRopeMethod: AC.Method ← AC.LookupMethodInStructure[$toRope, elementStructure];
inData: SequenceData ← NARROW[in.data];
out ← "< ";
out ← "( "; -- temp change 5/21/87 for SAC-2
FOR i:NAT IN [1..inData.lengthPlus1) DO
out ← Rope.Concat[ out, NARROW[AC.ApplyNoLkpNoRecastRef[toRopeMethod, LIST[inData[i] ] ] ] ];
IF i < inData.lengthPlus1-1 THEN out ← Rope.Concat[out,", "];
ENDLOOP;
out ← Rope.Concat[ out, " >" ];
out ← Rope.Concat[ out, " )" ]; -- temp change 5/21/87 for SAC-2
};
Write: PUBLIC AC.WriteOp ~ {
stream.PutRope[ ToRope[in] ]
};
Constructor
MakeSequence: PUBLIC AC.ListImbedOp ~ {
Attempts to recast supplied elements into elementStructure.
If data = NIL then returns a Sequence whose SequenceDataRec is of length 0.
structureData: SequenceStructureData ← NARROW[structure.data];
elementStructure: AC.Object ← structureData.elementStructure;
recastMethod: Method ← AC.LookupMethodInStructure[$recast, elementStructure];
length: NAT ← 0;
ptr: LIST OF AC.Object ← data;
outData: SequenceData;
WHILE ptr#NIL DO length ← length + 1; ptr ← ptr.rest ENDLOOP;
outData ← NEW[SequenceDataRec[length] ];
FOR i:NAT IN [1..length] DO
outData[i] ← AC.ApplyNoLkpNoRecastObject[recastMethod, LIST[data.first, elementStructure] ];
IF outData[i] = NIL THEN TypeError[];
data ← data.rest;
ENDLOOP;
out ← NEW[AC.ObjectRec ← [flavor: StructureElement, class: structure, data: outData] ];
};
Selection
Select: PUBLIC AC.BinaryOp ~ {
firstData: SequenceData ← NARROW[firstArg.data];
index: INT ← Ints.ToINT[secondArg];
IF index<1 OR firstData.lengthPlus1-1<index THEN RETURN[NIL];
RETURN[firstData[index] ];
};
First: PUBLIC AC.UnaryOp ~ {
firstArg = Sequence, return first element. Return NIL if empty.
RETURN[ Select[arg, Ints.FromINT[1] ] ];
};
Last: PUBLIC AC.UnaryOp ~ {
firstArg = Sequence, return last element. Return NIL if empty.
firstData: SequenceData ← NARROW[arg.data];
IF firstData.lengthPlus1-1=0 THEN RETURN[NIL];
RETURN[firstData[firstData.lengthPlus1-1] ];
};
Length: PUBLIC AC.ElementRankOp ~ {
data: SequenceData ← NARROW[arg.data];
RETURN[data.lengthPlus1-1];
};
Predicates
IsSubset: PUBLIC AC.BinaryPredicate ~ {
firstArg and secondArg are Sequences. Returns TRUE if firstArg is a subset of secondArg. Returns FALSE if args have different elementStructures.
firstSeqData: SequenceData ← NARROW[firstArg.data];
secondSeqData: SequenceData ← NARROW[secondArg.data];
firstStructureData: SequenceStructureData ← NARROW[firstArg.class.data];
secondStructureData: SequenceStructureData ← NARROW[firstArg.class.data];
firstElementStructure: Object ← firstStructureData.elementStructure;
secondElementStructure: Object ← firstStructureData.elementStructure;
intIndex: Ints.Int;
IF NOT AC.StructureEqual[firstElementStructure, secondElementStructure] THEN RETURN[FALSE];
FOR i:INT IN [1..firstSeqData.lengthPlus1) DO
intIndex ← Find[secondArg, firstSeqData[i] ];
IF intIndex=NIL THEN RETURN[FALSE];
ENDLOOP;
RETURN[TRUE];
};
Standard Desired Arg Structures
ObjectAndIntDesired: PUBLIC AC.UnaryToListOp ~ {
RETURN[ LIST[arg, Ints.Ints] ]; -- arg assumed to be a Sequence Structure
};
SequenceAndElementDesired: PUBLIC AC.UnaryToListOp ~ {
thisSequenceStructureData: SequenceStructureData ← NARROW[arg.data];
elementStructure: Object ← thisSequenceStructureData.elementStructure;
RETURN[ LIST[arg, elementStructure] ]; -- arg assumed to be a Sequence Structure
};
SequenceIntAndElementDesired: PUBLIC AC.UnaryToListOp ~ {
thisSequenceStructureData: SequenceStructureData ← NARROW[arg.data];
elementStructure: Object ← thisSequenceStructureData.elementStructure;
RETURN[ LIST[arg, Ints.Ints, elementStructure] ]; -- arg assumed to be a Sequence Structure
};
Operations
Paren: PUBLIC AC.UnaryOp ~ {
RETURN[NEW[AC.ObjectRec ← [
flavor: arg.flavor,
class: arg.class,
data: arg.data
] ] ];
};
Equal: PUBLIC AC.BinaryPredicate ~ {
firstArgData: SequenceData ← NARROW[firstArg.data];
secondArgData: SequenceData ← NARROW[secondArg.data];
sequenceStructureData: SequenceStructureData ← NARROW[firstArg.class.data];
elementEqualsMethod: Method ← AC.LookupMethodInStructure[$eqFormula, sequenceStructureData.elementStructure];
IF firstArgData.lengthPlus1 # secondArgData.lengthPlus1 THEN RETURN[FALSE];
FOR j: NAT IN [1..firstArgData.lengthPlus1) DO
IF NOT AC.ApplyPredNoLkpNoRecast[elementEqualsMethod, LIST[firstArgData[j], secondArgData[j] ] ] THEN RETURN[FALSE];
ENDLOOP;
RETURN[TRUE];
};
Prepend: PUBLIC AC.BinaryOp ~ {
RETURN[ Insert[firstArg, Ints.FromINT[0], secondArg] ];
};
Append: PUBLIC AC.BinaryOp ~ {
firstData: SequenceData ← NARROW[firstArg.data];
RETURN[ Insert[firstArg, Ints.FromINT[firstData.lengthPlus1 - 1], secondArg] ];
};
Insert: PUBLIC AC.TernaryOp ~ {
firstArg is a Sequence, secondArg is an Ints.Int specifying position after which to insert new item, thirdArg is new item. secondArg = 0 means insert at beginning, secondArg = i means insert after ith element of sequence. thirdArg must belong to firstArg's elementStructure.
Error if secondArg > Length[firstArg].
sequenceStructureData: SequenceStructureData ← NARROW[firstArg.class.data];
elementStructure: Object ← sequenceStructureData.elementStructure;
recastMethod: Method ← AC.LookupMethodInStructure[$recast, elementStructure];
newElement: Object ← AC.ApplyNoLkpNoRecastObject[recastMethod, LIST[thirdArg, elementStructure] ];
firstData: SequenceData ← NARROW[firstArg.data];
length: INT ← firstData.lengthPlus1 -1;
insertAfter: INT ← Ints.ToINT[secondArg];
newData: SequenceData;
IF insertAfter>length THEN ERROR;
IF newElement = NIL THEN TypeError[]; -- recast failed
newData ← NEW[SequenceDataRec[length+1] ];
FOR i:INT IN [1..insertAfter] DO newData[i] ← firstData[i] ENDLOOP;
newData[insertAfter+1] ← thirdArg;
FOR j:INT IN [insertAfter+1..length] DO newData[j+1] ← firstData[j] ENDLOOP;
RETURN[ NEW[AC.ObjectRec ← [
flavor: StructureElement,
class: firstArg.class,
data: newData
] ] ];
};
Delete: PUBLIC AC.BinaryOp ~ {
firstArg is a Sequence, secondArg is a positive Ints.Int specifying position to delete.
Error if secondArg<1 OR secondArg > Length[firstArg].
firstData: SequenceData ← NARROW[firstArg.data];
delete: INT ← Ints.ToINT[secondArg];
length: INT ← firstData.lengthPlus1-1;
newData: SequenceData;
IF delete<1 OR delete>length THEN ERROR;
newData ← NEW[SequenceDataRec[length-1] ];
FOR i:INT IN [1..delete-1] DO newData[i] ← firstData[i] ENDLOOP;
FOR j:INT IN [delete+1..length] DO newData[j-1] ← firstData[j] ENDLOOP;
RETURN[ NEW[AC.ObjectRec ← [
flavor: StructureElement,
class: firstArg.class,
data: newData
] ] ];
};
DeleteLast: PUBLIC AC.UnaryOp ~ {
data: SequenceData ← NARROW[arg.data];
IF data.lengthPlus1-1 = 0 THEN RETURN[arg];
RETURN[Delete[arg, Ints.FromINT[data.lengthPlus1-1] ] ];
};
Find: PUBLIC AC.BinaryOp ~ {
seqData: SequenceData ← NARROW[firstArg.data];
sequenceStructureData: SequenceStructureData ← NARROW[firstArg.class.data];
elementStructure: Object ← sequenceStructureData.elementStructure;
equalMethod: Method ← AC.LookupMethodInStructure[$eqFormula, elementStructure];
test: BOOL;
FOR i:INT IN [1..seqData.lengthPlus1) DO
test ← AC.ApplyPredNoLkpRecast[equalMethod, elementStructure, LIST[seqData[i], secondArg] ];
IF test THEN RETURN[Ints.FromINT[i] ];
ENDLOOP;
RETURN[NIL];
};
Concatenate: PUBLIC AC.BinaryOp ~ {
Concatenate two Sequences. Must have same elementStructure.
firstData: SequenceData ← NARROW[firstArg.data];
firstLengthPlus1: INT ← firstData.lengthPlus1;
secondData: SequenceData ← NARROW[secondArg.data];
newData: SequenceData ← NEW[SequenceDataRec[firstLengthPlus1+secondData.lengthPlus1-2] ];
IF NOT AC.StructureEqual[firstArg.class, secondArg.class] THEN ERROR;
FOR i:INT IN [1..firstLengthPlus1) DO newData[i] ← firstData[i] ENDLOOP;
FOR j:INT IN [firstLengthPlus1..firstLengthPlus1+secondData.lengthPlus1-1) DO newData[j] ← secondData[j - firstLengthPlus1 + 1] ENDLOOP;
RETURN[ NEW[AC.ObjectRec ← [
flavor: StructureElement,
class: firstArg.class,
data: newData
] ] ];
};
MapUnaryElementOp: PUBLIC AC.BinaryMixedOp ~ {
firstArg is a Sequence, secondArg is a unary Method (e.g. UnaryOp, UnaryPredicate) on its elementStructure, result is Sequence of results of applications of the unary operation to the elements of firstArg.
seqData: SequenceData ← NARROW[firstArg.data];
method: Method ← NARROW[secondArg];
newElementStructure, newSeqStructure: AC.Object ← NIL;
newData: SequenceData ← NEW[SequenceDataRec[seqData.lengthPlus1-1] ];
FOR i:INT IN [1..seqData.lengthPlus1) DO
newData[i] ← AC.ApplyNoLkpNoRecastObject[method, LIST[seqData[i] ] ];
IF newData[i]# NIL THEN newElementStructure ← newData[i].class;
ENDLOOP;
IF newElementStructure = NIL THEN RETURN[firstArg]; -- map has trivial result
newSeqStructure ← MakeSequenceStructure[newElementStructure];
RETURN[ NEW[AC.ObjectRec ← [
flavor: StructureElement,
class: newSeqStructure,
data: newData
] ] ];
};
Start Code
sequencesClass: AC.Object ← AC.MakeClass["SequenceClass", NIL, NIL];
setCategoryMethod: Method ← AC.MakeMethod[Value, FALSE, NEW[AC.Category ← set], NIL, NIL];
sequenceStructureMethod: Method ← AC.MakeMethod[Value, FALSE, NIL, NIL, "sequenceStructure"];
shortPrintNameMethod: Method ← AC.MakeMethod[ToRopeOp, FALSE, NEW[AC.ToRopeOp ← ShortPrintName], NIL, "shortPrintName"];
recastMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Recast], NIL, "recast"];
canRecastMethod: Method ← AC.MakeMethod[BinaryPredicate, TRUE, NEW[AC.BinaryPredicate ← CanRecast], NIL, "canRecast"];
toExprMethod: Method ← AC.MakeMethod[ToExprOp, FALSE, NEW[AC.ToExprOp ← ToExpr], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "toExpr"];
legalFirstCharMethod: Method ← AC.MakeMethod[LegalFirstCharOp, FALSE, NEW[AC.LegalFirstCharOp ← LegalFirstChar], NIL, "legalFirstChar"];
readMethod: Method ← AC.MakeMethod[ReadOp, FALSE, NEW[AC.ReadOp ← Read], NIL, "read"];
fromRopeMethod: Method ← AC.MakeMethod[FromRopeOp, TRUE, NEW[AC.FromRopeOp ← FromRope], NIL, "fromRope"];
toRopeMethod: Method ← AC.MakeMethod[ToRopeOp, FALSE, NEW[AC.ToRopeOp ← ToRope], NIL, "toRope"];
parenMethod: Method ← AC.MakeMethod[UnaryOp, FALSE, NEW[AC.UnaryOp ← Paren], NIL, "paren"];
sequenceMethod: Method ← AC.MakeMethod[ListImbedOp, FALSE, NEW[AC.ListImbedOp ← MakeSequence], NIL, "sequence"];
selectMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Select], NEW[AC.UnaryToListOp ← ObjectAndIntDesired], "select"];
firstMethod: Method ← AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp ← First], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "first"];
lastMethod: Method ← AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp ← Last], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "last"];
lengthMethod: Method ← AC.MakeMethod[ElementRankOp, TRUE, NEW[AC.ElementRankOp ← Length], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "length"];
subsetMethod: Method ← AC.MakeMethod[BinaryPredicate, TRUE, NEW[AC.BinaryPredicate ← IsSubset], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "subset"];
equalMethod: Method ← AC.MakeMethod[BinaryPredicate, TRUE, NEW[AC.BinaryPredicate ← Equal], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "equals"];
prependMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Prepend], NEW[AC.UnaryToListOp ← SequenceAndElementDesired], "prepend"];
appendMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Append], NEW[AC.UnaryToListOp ← SequenceAndElementDesired], "append"];
insertMethod: Method ← AC.MakeMethod[TernaryOp, FALSE, NEW[AC.TernaryOp ← Insert], NEW[AC.UnaryToListOp ← SequenceIntAndElementDesired], "insert"]; -- not an operator currently since takes three args
deleteMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Delete], NEW[AC.UnaryToListOp ← ObjectAndIntDesired], "delete"];
deleteLastMethod: Method ← AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp ← DeleteLast], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "deleteLast"];
findMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Find], NEW[AC.UnaryToListOp ← SequenceAndElementDesired], "find"];
concatenateMethod: Method ← AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp ← Concatenate], NEW[AC.UnaryToListOp ← AC.DefaultDesiredArgStructures], "concatenate"];
mapUnaryElementOpMethod: Method ← AC.MakeMethod[BinaryMixedOp, TRUE, NEW[AC.BinaryMixedOp ← MapUnaryElementOp], NIL, "mapUnary"]; -- have to have DesiredArgStructures ← NIL since BinaryMixedOp
makeSequenceStructureMethod: Method ← AC.MakeMethod[SequenceStructureConstructor, FALSE, NEW[AC.SequenceStructureConstructor ← MakeSequenceStructure], NIL, "makeSequenceStructure"];
AC.AddMethodToClass[$category, setCategoryMethod, sequencesClass];
AC.AddMethodToClass[$sequenceStructure, sequenceStructureMethod, sequencesClass];
AC.AddMethodToClass[$shortPrintName, shortPrintNameMethod, sequencesClass];
AC.AddMethodToClass[$recast, recastMethod, sequencesClass];
AC.AddMethodToClass[$canRecast, canRecastMethod, sequencesClass];
AC.AddMethodToClass[$toExpr, toExprMethod, sequencesClass];
AC.AddMethodToClass[$legalFirstChar, legalFirstCharMethod, sequencesClass];
AC.AddMethodToClass[$read, readMethod, sequencesClass];
AC.AddMethodToClass[$fromRope, fromRopeMethod, sequencesClass];
AC.AddMethodToClass[$toRope, toRopeMethod, sequencesClass];
AC.AddMethodToClass[$paren, parenMethod, sequencesClass];
AC.AddMethodToClass[$sequence, sequenceMethod, sequencesClass];
AC.AddMethodToClass[$select, selectMethod, sequencesClass];
AC.AddMethodToClass[$first, firstMethod, sequencesClass];
AC.AddMethodToClass[$last, lastMethod, sequencesClass];
AC.AddMethodToClass[$length, lengthMethod, sequencesClass];
AC.AddMethodToClass[$subset, subsetMethod, sequencesClass];
AC.AddMethodToClass[$eqFormula, equalMethod, sequencesClass];
AC.AddMethodToClass[$prepend, prependMethod, sequencesClass];
AC.AddMethodToClass[$append, appendMethod, sequencesClass];
AC.AddMethodToClass[$insert, insertMethod, sequencesClass];
AC.AddMethodToClass[$delete, deleteMethod, sequencesClass];
AC.AddMethodToClass[$deleteLast, deleteLastMethod, sequencesClass];
AC.AddMethodToClass[$find, findMethod, sequencesClass];
AC.AddMethodToClass[$concatenate, concatenateMethod, sequencesClass];
AC.AddMethodToClass[$mapUnary, mapUnaryElementOpMethod, sequencesClass];
AC.AddMethodToClass[$makeSequenceStructure, makeSequenceStructureMethod, Structures.StructuresClass];
END.