BiRelsInverting.Mesa
Last tweaked by Mike Spreitzer on January 19, 1988 2:33:33 pm PST
DIRECTORY AbSets, Atom, BiRelBasics, BiRels, BiRelsPrivate, IntStuff, SetBasics;
BiRelsInverting:
CEDAR
PROGRAM
IMPORTS AbSets, Atom, BiRelBasics, BiRels, SetBasics
EXPORTS BiRels
=
BEGIN OPEN SetBasics, Sets:AbSets, Sets, BiRelBasics, BiRels;
Invert:
PUBLIC
PROC [br: BiRel]
RETURNS [BiRel] ~ {
IF br.class = invClasses [br.Functional[][leftToRight]] [br.Functional[][rightToLeft]] [br.MutabilityOf] THEN RETURN DeRef[br.data];
RETURN [[
invClasses
[br.Functional[][rightToLeft]]
[br.Functional[][leftToRight]]
[br.MutabilityOf],
br.Refify]]};
InvClasses: TYPE ~ ARRAY BOOL OF ARRAY BOOL OF ARRAY Mutability OF BiRelClass;
invClasses: REF InvClasses ~ NEW [InvClasses];
kindKey: ATOM ~ $BiRelsImplKind;
InvPrimitive:
PROC [br: BiRel, op:
ATOM, arg1, arg2:
REF
ANY]
RETURNS [PrimitiveAnswer] ~ {
SELECT op
FROM
$HasPair, $Image, $Apply, $ScanRestriction, $GetOne, $Get3, $RestrictionSize, $GetBounds, $Copy, $Insulate, $ValueOf, $Freeze, $Thaw, $SetOn, $CurSetOn, $AddPair, $AddSet, $Swap, $RemPair, $RemSet, $Update, $Delete, $DeleteSet, $Spaces, $IsDense, $SideFixed => {
rbr: REF BiRel ~ NARROW[br.data];
WITH Atom.GetProp[op, kindKey]
SELECT
FROM
a:
ATOM =>
SELECT a
FROM
$always => ERROR;
$argless => IF arg1#NIL THEN ERROR;
$composite => ERROR;
ENDCASE => ERROR;
types:
REF BiRelsPrivate.ArgTyping => {
arg1 ← InvArg[arg1, types[1]];
arg2 ← InvArg[arg2, types[2]];
};
ENDCASE => ERROR;
RETURN [IF rbr^.GoodImpl[op, arg1, arg2] THEN yes ELSE no];
};
ENDCASE => RETURN [no];
};
InvArg:
PROC [arg:
REF
ANY, type: BiRelsPrivate.ArgType]
RETURNS [
REF
ANY] ~ {
this:
REF
ANY ~
SELECT type
FROM
$EndBools, $limit, $remove, $Set, $Want3, $When => arg,
$BiRel => ToBiRel[arg]^.Invert.Refify,
$Dir => FromDir[OtherDirection[ToDir[arg]]],
$None => IF arg=NIL THEN arg ELSE ERROR,
$RelOrder, $RelOrderFN => FromRO[InvertRelOrder[ToRO[arg]]],
$SetPair => FromSets[InvertSetPair[ToSets[arg]^]],
$Side => FromSide[OtherSide[ToSide[arg]]],
ENDCASE => ERROR;
RETURN [this]};
InvHasPair:
PROC [br: BiRel, pair: Pair]
RETURNS [
BOOL] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.HasPair[InvertPair[pair]]};
InvImage:
PROC [br: BiRel, set: Set, dir: Direction]
RETURNS [Set] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.Image[set, OtherDirection[dir]]};
InvApply:
PROC [br: BiRel, v: Value, dir: Direction]
RETURNS [MaybeValue] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.Apply[v, OtherDirection[dir]]};
InvScanRestriction:
PROC [br: BiRel, sets: SetPair,
Test: Tester, ro: RelOrder]
RETURNS [MaybePair] ~ {
rbr: REF BiRel ~ NARROW[br.data];
Pass: PROC [pair: Pair] RETURNS [BOOL] ~ {RETURN Test[InvertPair[pair]]};
RETURN rbr^.ScanRestriction[InvertSetPair[sets], Pass, ro.InvertRelOrder].InvertMaybe};
InvGetOne:
PROC [br: BiRel, remove:
BOOL, ro: RelOrder]
RETURNS [MaybePair] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.GetOne[remove, ro.InvertRelOrder].InvertMaybe};
InvGet3:
PROC [br: BiRel, pair: Pair, ro: RelOrder, want: TripleBool]
RETURNS [TripleMaybePair] ~ {
rbr: REF BiRel ~ NARROW[br.data];
tmp: TripleMaybePair ~ rbr^.Get3[InvertPair[pair], InvertRelOrder[ro], want];
RETURN [[tmp.prev.InvertMaybe, tmp.same.InvertMaybe, tmp.next.InvertMaybe]]};
InvRestrictionSize:
PROC [br: BiRel, sets: SetPair, limit:
EINT]
RETURNS [
EINT] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.RestrictionSize[InvertSetPair[sets], limit]};
InvGetBounds:
PROC [br: BiRel, want: EndBools, ro: RelOrder]
RETURNS [MaybePairInterval] ~ {
rbr: REF BiRel ~ NARROW[br.data];
mpi: MaybePairInterval ~ rbr^.GetBounds[want, InvertRelOrder[ro]];
RETURN [[mpi.found, [InvertPair[mpi.it[min]], InvertPair[mpi.it[max]]]]]};
InvCopy:
PROC [br: BiRel]
RETURNS [VarBiRel] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.Copy.Invert.AsVar};
InvInsulate:
PROC [br: BiRel]
RETURNS [UWBiRel] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.Insulate.Invert.AsUW};
InvValueOf:
PROC [br: BiRel]
RETURNS [ConstBiRel] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.ValueOf.Invert.AsConst};
InvFreeze:
PROC [br: BiRel]
RETURNS [ConstBiRel] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.Freeze.Invert.AsConst};
InvThaw:
PROC [br: BiRel] ~ {
rbr: REF BiRel ~ NARROW[br.data];
rbr^.Thaw[];
RETURN};
InvSetOn:
PROC [br: BiRel, side: Side]
RETURNS [UWSet] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.SetOn[OtherSide[side]]};
InvCurSetOn:
PROC [br: BiRel, side: Side]
RETURNS [ConstSet] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.CurSetOn[OtherSide[side]]};
InvAddPair:
PROC [br: BiRel, pair: Pair, if: IfHadPair ← alwaysAdd]
RETURNS [had: HadPair] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN [InvertHadPair[rbr^.AddPair[pair, InvertIfHadPair[if]]]]};
InvAddSet:
PROC [br, other: BiRel, if: IfHadPair]
RETURNS [some: HadSetPair] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN [InvertHadSetPair[rbr^.AddSet[other.Invert, InvertIfHadPair[if]]]]};
InvSwap:
PROC [br: BiRel, a, b: Value, side: Side] ~ {
rbr: REF BiRel ~ NARROW[br.data];
rbr^.Swap[a, b, OtherSide[side]];
RETURN};
InvRemPair:
PROC [br: BiRel, pair: Pair]
RETURNS [had: HadPair] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN [InvertHadPair[rbr^.RemPair[pair]]]};
InvRemSet:
PROC [br, other: BiRel]
RETURNS [some: HadSetPair] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN [InvertHadSetPair[rbr^.RemSet[other.Invert]]]};
InvUpdate:
PROC [br: BiRel, val: Value, dir: Direction,
Decide: UpdateDecider] ~ {
rbr: REF BiRel ~ NARROW[br.data];
rbr^.Update[val, OtherDirection[dir], Decide];
RETURN};
InvDelete:
PROC [br: BiRel, val: Value, side: Side ← left]
RETURNS [hadSome:
BOOL] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.Delete[val, OtherSide[side]]};
InvDeleteSet:
PROC [br: BiRel, set: Set, side: Side]
RETURNS [had: SomeAll] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.DeleteSet[set, OtherSide[side]]};
InvSpaces:
PROC [br: BiRel]
RETURNS [SpacePair] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN InvertSpacePair[rbr^.Spaces]};
InvIsDense:
PROC [br: BiRel, when: When, side: Side]
RETURNS [
BOOL] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.IsDense[when, OtherSide[side]]};
InvSideFixed:
PROC [br: BiRel, side: Side]
RETURNS [
BOOL] ~ {
rbr: REF BiRel ~ NARROW[br.data];
RETURN rbr^.SideFixed[OtherSide[side]]};
Start:
PROC ~ {
FOR l2r:
BOOL
IN
BOOL
DO
FOR r2l:
BOOL
IN
BOOL
DO
FOR mut: Mutability
IN Mutability
DO
invClasses[l2r][r2l][mut] ← CreateClass[[
Primitive: InvPrimitive,
HasPair: InvHasPair,
Image: InvImage,
Apply: InvApply,
ScanRestriction: InvScanRestriction,
GetOne: InvGetOne,
Get3: InvGet3,
RestrictionSize: InvRestrictionSize,
GetBounds: InvGetBounds,
Copy: InvCopy,
Insulate: IF mut=variable THEN InvInsulate ELSE NIL,
ValueOf: IF mut#constant THEN InvValueOf ELSE NIL,
Freeze: IF mut=variable THEN InvFreeze ELSE NIL,
Thaw: IF mut=variable THEN InvThaw ELSE NIL,
SetOn: InvSetOn,
CurSetOn: InvCurSetOn,
AddPair: IF mut=variable THEN InvAddPair ELSE NIL,
AddSet: IF mut=variable THEN InvAddSet ELSE NIL,
Swap: IF mut=variable THEN InvSwap ELSE NIL,
RemPair: IF mut=variable THEN InvRemPair ELSE NIL,
RemSet: IF mut=variable THEN InvRemSet ELSE NIL,
Update: InvUpdate,
Delete: IF mut=variable THEN InvDelete ELSE NIL,
DeleteSet: IF mut=variable THEN InvDeleteSet ELSE NIL,
Spaces: InvSpaces,
IsDense: InvIsDense,
SideFixed: InvSideFixed,
functional: [l2r, r2l],
mutability: mut]];
ENDLOOP ENDLOOP ENDLOOP;
RETURN};
Start[];
END.