DIRECTORY AbSets, Atom, Basics, BiRelBasics, IntStuff, IO, SetBasics; BiRels: CEDAR DEFINITIONS IMPORTS AbSets, BiRelBasics, IntStuff, SetBasics = {OPEN IntStuff, SetBasics, Sets:AbSets, Sets, BiRelBasics; EINT: TYPE ~ IntStuff.EINT; Value: TYPE ~ SetBasics.Value; Interval: TYPE ~ SetBasics.Interval; IntInterval: TYPE ~ SetBasics.IntInterval; Set: TYPE ~ Sets.Set; Direction: TYPE ~ Sets.Direction; Side: TYPE ~ Sets.Side; Pair: TYPE ~ BiRelBasics.Pair; noPair: READONLY Pair; LOP: TYPE ~ LIST OF Pair; MaybePair: TYPE ~ BiRelBasics.MaybePair; noMaybePair: READONLY MaybePair; TripleMaybePair: TYPE ~ BiRelBasics.TripleMaybePair; MaybePairInterval: TYPE ~ BiRelBasics.MaybePairInterval; MaybePairSpace: TYPE ~ BiRelBasics.MaybePairSpace; Had: TYPE ~ BiRelBasics.Had; HadPair: TYPE ~ BiRelBasics.HadPair; HadSetPair: TYPE ~ BiRelBasics.HadSetPair; IfHad: TYPE ~ BiRelBasics.IfHad; IfHadPair: TYPE ~ BiRelBasics.IfHadPair; alwaysAdd: IfHadPair ~ BiRelBasics.alwaysAdd; addIfNew: IfHadPair ~ BiRelBasics.addIfNew; addIfOld: IfHadPair ~ BiRelBasics.addIfOld; BoolPair: TYPE ~ BiRelBasics.BoolPair; SpacePair: TYPE ~ BiRelBasics.SpacePair; SetPair: TYPE ~ BiRelBasics.SetPair; PairInterval: TYPE ~ BiRelBasics.PairInterval; RelOrder: TYPE ~ BiRelBasics.RelOrder; TotalRelOrder: TYPE ~ BiRelBasics.TotalRelOrder; leftFwd: RelOrder ~ BiRelBasics.leftFwd; leftBwd: RelOrder ~ BiRelBasics.leftBwd; rightFwd: RelOrder ~ BiRelBasics.rightFwd; rightBwd: RelOrder ~ BiRelBasics.rightBwd; PairSpace: TYPE ~ BiRelBasics.PairSpace; BiRel: TYPE ~ RECORD [class: BiRelClass, data: REF ANY]; ConsBiRel: PROC [class: BiRelClass, data: REF ANY] RETURNS [BiRel]; nilBiRel: BiRel ~ [NIL, NIL]; badBiRel: READONLY BiRel; DeRef: PROC [ra: REF ANY] RETURNS [BiRel] ~ INLINE {RETURN [IF ra#NIL THEN NARROW[ra, RefBiRel]^ ELSE nilBiRel]}; Refify: PROC [br: BiRel] RETURNS [RefBiRel] ~ INLINE {RETURN [NEW [BiRel _ br]]}; Cant: ERROR [br: BiRel]; AsSet: PROC [br: BiRel, ro: RelOrder] RETURNS [Set--of REF Pair--] ~ INLINE {RETURN br.class.AsSet[br, ro]}; HasPair: PROC [br: BiRel, pair: Pair] RETURNS [BOOL] ~ INLINE {RETURN br.class.HasPair[br, pair]}; HasAA: PROC [br: BiRel, left, right: REF ANY] RETURNS [BOOL] ~ INLINE {RETURN br.class.HasPair[br, [AV[left], AV[right]]]}; HasIA: PROC [br: BiRel, left: INT, right: REF ANY] RETURNS [BOOL] ~ INLINE {RETURN br.class.HasPair[br, [IV[left], AV[right]]]}; HasII: PROC [br: BiRel, left, right: INT] RETURNS [BOOL] ~ INLINE {RETURN br.class.HasPair[br, [IV[left], IV[right]]]}; Image: PROC [br: BiRel, set: Set, dir: Direction _ leftToRight] RETURNS [Set] ~ INLINE {RETURN br.class.Image[br, set, dir]}; Mapping: PROC [br: BiRel, v: Value, dir: Direction _ leftToRight] RETURNS [Set] ~ INLINE {RETURN br.class.Image[br, Sets.CreateSingleton[v, br.Spaces[][Source[dir]]], dir]}; MappingA: PROC [br: BiRel, v: REF ANY, dir: Direction _ leftToRight] RETURNS [Set] ~ INLINE {RETURN br.class.Image[br, Sets.CreateSingleton[AV[v], br.Spaces[][Source[dir]]], dir]}; MappingI: PROC [br: BiRel, v: INT, dir: Direction _ leftToRight] RETURNS [Set] ~ INLINE {RETURN br.class.Image[br, Sets.CreateSingleton[IV[v], br.Spaces[][Source[dir]]], dir]}; HasMapping: PROC [br: BiRel, v: Value, dir: Direction _ leftToRight] RETURNS [BOOL] ~ INLINE {from: Side ~ Source[dir]; RETURN [br.class.ScanRestriction[br, ConsSets[from, Sets.CreateSingleton[v, br.Spaces[][from]]], AcceptAny, []].found]}; HasMapA: PROC [br: BiRel, v: REF ANY, dir: Direction _ leftToRight] RETURNS [BOOL] ~ INLINE {from: Side ~ Source[dir]; RETURN [br.class.ScanRestriction[br, ConsSets[from, Sets.CreateSingleton[AV[v], br.Spaces[][from]]], AcceptAny, []].found]}; HasMapI: PROC [br: BiRel, v: INT, dir: Direction _ leftToRight] RETURNS [BOOL] ~ INLINE {from: Side ~ Source[dir]; RETURN [br.class.ScanRestriction[br, ConsSets[from, Sets.CreateSingleton[IV[v], br.Spaces[][from]]], AcceptAny, []].found]}; Enumerate: PROC [br: BiRel, Consume: PROC [Pair], ro: RelOrder _ []]; EnumAA: PROC [br: BiRel, Consume: PROC [REF ANY, REF ANY], ro: RelOrder _ []]; EnumIA: PROC [br: BiRel, Consume: PROC [INT, REF ANY], ro: RelOrder _ []]; EnumII: PROC [br: BiRel, Consume: PROC [INT, INT], ro: RelOrder _ []]; Tester: TYPE ~ PROC [Pair] RETURNS [BOOL]; AcceptAny: Tester--={RETURN[TRUE]}--; Scan: PROC [br: BiRel, Test: Tester, ro: RelOrder _ []] RETURNS [MaybePair] ~ INLINE {RETURN br.class.ScanRestriction[br, [], Test, ro]}; EnumerateImage: PROC [br: BiRel, set: Set, Consume: PROC [Value], dir: Direction _ leftToRight, ro: Sets.RelOrder _ no]; EnumerateMapping: PROC [br: BiRel, v: Value, Consume: PROC [Value], dir: Direction _ leftToRight, ro: Sets.RelOrder _ no] ~ INLINE {EnumerateImage[br, Sets.CreateSingleton[v, br.Spaces[][Source[dir]]], Consume, dir, ro]}; EnumerateHalfRestriction: PROC [br: BiRel, set: Set, Consume: PROC [Pair], side: Side _ left, ro: RelOrder _ []]; ScanImage: PROC [br: BiRel, set: Set, Test: Sets.Tester, dir: Direction _ leftToRight, ro: Sets.RelOrder _ no] RETURNS [MaybePair]; ScanMapping: PROC [br: BiRel, v: Value, Test: Sets.Tester, dir: Direction _ leftToRight, ro: Sets.RelOrder _ no] RETURNS [MaybePair] ~ INLINE {RETURN ScanImage[br, Sets.CreateSingleton[v, br.Spaces[][Source[dir]]], Test, dir, ro]}; ScanRestriction: PROC [br: BiRel, sets: SetPair _ [], Test: Tester, ro: RelOrder _ []] RETURNS [MaybePair] ~ INLINE {RETURN br.class.ScanRestriction[br, sets, Test, ro]}; ScanHalfRestriction: PROC [br: BiRel, set: Set, Test: Tester, side: Side _ left, ro: RelOrder _ []] RETURNS [MaybePair] ~ INLINE {RETURN br.class.ScanRestriction[br, ConsSets[side, set], Test, ro]}; ParallelScan: PROC [a, b: BiRel, Test: ParallelTester, roA, roB: RelOrder _ []] RETURNS [ParallelFind] ~ INLINE {RETURN ParallelScanRestriction[a, b, Test, [], [], roA, roB]}; ParallelScanRestriction: PROC [a, b: BiRel, Test: ParallelTester, setsA, setsB: SetPair _ [], roA, roB: RelOrder _ []] RETURNS [ParallelFind]; ParallelTester: TYPE ~ PROC [a, b: MaybePair] RETURNS [pass: BOOL _ FALSE]; ParallelFind: TYPE ~ RECORD [found: BOOL, a, b: MaybePair]; InterleavedProduceRestriction: PROC [a, b: BiRel, Consume: InterleavedConsumer, setsA, setsB: SetPair _ [], roA, roB: RelOrder _ []] RETURNS [MaybePair]; InterleavedConsumer: TYPE ~ PROC [PROC [Which] RETURNS [MaybePair]] RETURNS [MaybePair]; GetOne: PROC [br: BiRel, remove: BOOL, ro: RelOrder] RETURNS [MaybePair] ~ INLINE {RETURN br.class.GetOne[br, remove, ro]}; APair: PROC [br: BiRel, ro: RelOrder _ []] RETURNS [MaybePair] ~ INLINE {RETURN br.class.GetOne[br, FALSE, ro]}; Pop: PROC [br: BiRel, ro: RelOrder _ []] RETURNS [MaybePair] ~ INLINE {RETURN br.class.GetOne[br, TRUE, ro]}; First: PROC [br: BiRel] RETURNS [MaybePair] ~ INLINE {RETURN br.class.GetOne[br, FALSE, [ALL[fwd]]]}; Last: PROC [br: BiRel] RETURNS [MaybePair] ~ INLINE {RETURN br.class.GetOne[br, FALSE, [ALL[bwd]]]}; Next: PROC [br: BiRel, pair: Pair, ro: RelOrder _ [[fwd, no]]] RETURNS [MaybePair] ~ INLINE {RETURN [br.class.Get3[br, pair, ro, [FALSE, FALSE, TRUE]].next]}; Prev: PROC [br: BiRel, pair: Pair, ro: RelOrder _ [[fwd, no]]] RETURNS [MaybePair] ~ INLINE {RETURN [br.class.Get3[br, pair, ro, [TRUE, FALSE, FALSE]].prev]}; Get3: PROC [br: BiRel, pair: Pair, ro: RelOrder _ [[fwd, no]], want: TripleBool _ []] RETURNS [TripleMaybePair] ~ INLINE {RETURN br.class.Get3[br, pair, ro, want]}; SkipTo: PROC [br: BiRel, goal: Set, bounds: Interval _ fullInterval, side: Side _ right, bwd: BOOL _ FALSE] RETURNS [MaybePair] ~ INLINE {os: Side ~ OtherSide[side]; RETURN br.ScanRestriction[ConsSets[side, goal, IntervalAsSet[br.Spaces[][os], bounds]], AcceptAny, ConsRelOrder[os, IF bwd THEN bwd ELSE fwd]]}; Lookup: PROC [br: BiRel, goal: Value, bounds: Interval _ fullInterval, side: Side _ right, bwd: BOOL _ FALSE] RETURNS [MaybeValue] ~ INLINE {RETURN br.SkipTo[Sets.CreateSingleton[goal, br.Spaces[][side]], bounds, side, bwd].KeepHalf[OtherSide[side]]}; Size: PROC [br: BiRel, limit: EINT _ lastEINT] RETURNS [EINT] ~ INLINE {RETURN [br.class.RestrictionSize[br, [], limit]]}; Empty: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [br.Size[one]=zero]}; RestrictionSize: PROC [br: BiRel, sets: SetPair _ [], limit: EINT _ lastEINT] RETURNS [EINT] ~ INLINE {RETURN br.class.RestrictionSize[br, sets, limit]}; ImageSize: PROC [br: BiRel, set: Set, dir: Direction _ leftToRight, limit: EINT _ lastEINT] RETURNS [EINT]; MappingSize: PROC [br: BiRel, v: Value, dir: Direction _ leftToRight, limit: EINT _ lastEINT] RETURNS [EINT] ~ INLINE {RETURN ImageSize[br, Sets.CreateSingleton[v, br.Spaces[][Source[dir]]], dir, limit]}; MappingEmpty: PROC [br: BiRel, v: Value, dir: Direction _ leftToRight] RETURNS [BOOL] ~ INLINE {RETURN [MappingSize[br, v, dir, one]=zero]}; IsDense: PROC [br: BiRel, when: When _ always, side: Side _ left] RETURNS [BOOL] ~ INLINE {RETURN br.class.IsDense[br, when, side]}; denseSide: READONLY ROPE; --complaint raised when a caller tries an operation that would put a hole in a necessarily dense side of a BiRel. SideFixed: PROC [br: BiRel, side: Side _ left] RETURNS [BOOL] ~ INLINE {RETURN br.class.SideFixed[br, side]}; fixedSide: READONLY ROPE; --complaint raised when a caller tries an operation that would change a fixed side of a BiRel. GetBounds: PROC [br: BiRel, want: EndBools _ [], ro: RelOrder _ [[fwd, no]]] RETURNS [MaybePairInterval] ~ INLINE {RETURN br.class.GetBounds[br, want, ro]}; MutabilityOf: PROC [br: BiRel] RETURNS [Mutability] ~ INLINE {RETURN [br.class.mutability]}; Copy: PROC [br: BiRel] RETURNS [VarBiRel] ~ INLINE {RETURN br.class.Copy[br]}; Insulate: PROC [br: BiRel] RETURNS [UWBiRel] ~ INLINE {RETURN br.class.Insulate[br]}; ValueOf: PROC [br: BiRel] RETURNS [ConstBiRel] ~ INLINE {RETURN br.class.ValueOf[br]}; Freeze: PROC [br: BiRel] RETURNS [ConstBiRel] ~ INLINE {RETURN br.class.Freeze[br]}; Thaw: PROC [br: BiRel] ~ INLINE {br.class.Thaw[br]}; Has: PROC [br, other: BiRel, want: BoolPair] RETURNS [HadSetPair]; AddPair: PROC [br: BiRel, pair: Pair, if: IfHadPair _ alwaysAdd] RETURNS [had: HadPair] ~ INLINE {RETURN br.class.AddPair[br, pair, if]}; AddAA: PROC [br: BiRel, left, right: REF ANY, if: IfHadPair _ alwaysAdd] RETURNS [had: HadPair]; AddIA: PROC [br: BiRel, left: INT, right: REF ANY, if: IfHadPair _ alwaysAdd] RETURNS [had: HadPair]; AddII: PROC [br: BiRel, left, right: INT, if: IfHadPair _ alwaysAdd] RETURNS [had: HadPair]; AddNewPair: PROC [br: BiRel, pair: Pair]; AddNewAA: PROC [br: BiRel, left, right: REF ANY]; AddNewIA: PROC [br: BiRel, left: INT, right: REF ANY]; AddNewII: PROC [br: BiRel, left, right: INT]; AddSet: PROC [br, other: BiRel, if: IfHadPair _ alwaysAdd] RETURNS [some: HadSetPair] ~ INLINE {RETURN br.class.AddSet[br, other, if]}; AddNewSet: PROC [br, other: BiRel]; Swap: PROC [br: BiRel, a, b: Value, side: Side _ left] ~ INLINE {br.class.Swap[br, a, b, side]}; RemPair: PROC [br: BiRel, pair: Pair] RETURNS [had: HadPair] ~ INLINE {RETURN br.class.RemPair[br, pair]}; RemAA: PROC [br: BiRel, left, right: REF ANY] RETURNS [had: HadPair]; RemIA: PROC [br: BiRel, left: INT, right: REF ANY] RETURNS [had: HadPair]; RemII: PROC [br: BiRel, left, right: INT] RETURNS [had: HadPair]; RemOldPair: PROC [br: BiRel, pair: Pair]; RemOldAA: PROC [br: BiRel, left, right: REF ANY]; RemOldIA: PROC [br: BiRel, left: INT, right: REF ANY]; RemOldII: PROC [br: BiRel, left, right: INT]; RemSet: PROC [br, other: BiRel] RETURNS [some: HadSetPair] ~ INLINE {RETURN br.class.RemSet[br, other]}; Erase: PROC [br: BiRel] ~ INLINE {[] _ br.RemSet[br]}; Delete: PROC [br: BiRel, val: Value, side: Side _ left] RETURNS [hadSome: BOOL] ~ INLINE {RETURN br.class.Delete[br, val, side]}; DeleteA: PROC [br: BiRel, val: REF ANY, side: Side _ left] RETURNS [hadSome: BOOL] ~ INLINE {RETURN br.class.Delete[br, AV[val], side]}; DeleteI: PROC [br: BiRel, val: INT, side: Side _ left] RETURNS [hadSome: BOOL] ~ INLINE {RETURN br.class.Delete[br, IV[val], side]}; DeleteSet: PROC [br: BiRel, set: Set, side: Side _ left] RETURNS [had: SomeAll] ~ INLINE {RETURN br.class.DeleteSet[br, set, side]}; Substitute: PROC [br: BiRel, old, new: Value, side: Side]; SubstituteA: PROC [br: BiRel, old, new: REF ANY, side: Side] ~ INLINE {br.Substitute[AV[old], AV[new], side]}; SubstituteI: PROC [br: BiRel, old, new: INT, side: Side] ~ INLINE {br.Substitute[IV[old], IV[new], side]}; Spaces: PROC [br: BiRel] RETURNS [SpacePair] ~ INLINE {RETURN br.class.Spaces[br]}; SetOn: PROC [br: BiRel, side: Side] RETURNS [UWSet] ~ INLINE {RETURN [br.class.SetOn[br, side]]}; CurSetOn: PROC [br: BiRel, side: Side] RETURNS [ConstSet] ~ INLINE {RETURN br.class.CurSetOn[br, side]}; Functional: PROC [br: BiRel] RETURNS [BoolPair] ~ INLINE {RETURN [br.class.functional]}; Equal: PROC [a, b: BiRel, bounds: SetPair _ []] RETURNS [BOOL]; Hash: PROC [br: BiRel, bounds: SetPair _ []] RETURNS [CARDINAL]; Compare: PROC [a, b: BiRel, bounds: SetPair _ [], tro: TotalRelOrder _ [ALL[fwd]]] RETURNS [Comparison]; CreateBiRelSpace: PROC [eltSpaces: SpacePair] RETURNS [Space]; QuaBiRelSpace: PROC [Space] RETURNS [found: BOOL, eltSpaces: SpacePair]; PrintBiRel: PROC [br: BiRel, to: IO.STREAM, depth: INT _ 4, length: INT _ 32, verbose: BOOL _ FALSE]; FormatBiRel: PROC [br: BiRel, depth: INT _ 4, length: INT _ 32, verbose: BOOL _ FALSE] RETURNS [ROPE]; SetIsBiRel: PROC [set: Set] RETURNS [BOOL] ~ INLINE {RETURN [set.class.QuaBiRel[set].found]}; SetAsBiRel: PROC [set: Set] RETURNS [BiRel] ~ INLINE {RETURN [SetQuaBiRel[set].it]}; SetQuaBiRel: PROC [set: Set] RETURNS [MaybeBiRel] ~ INLINE { found: BOOL; class, data: REF ANY; [found, class, data] _ set.class.QuaBiRel[set]; RETURN [IF found THEN [TRUE, [NARROW[class], data]] ELSE [FALSE, badBiRel]]}; VarBiRel: TYPE ~ RECORD [BiRel] --a variable BiRel--; IsVar: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [br.class.mutability=variable]}; AsVar: PROC [br: BiRel] RETURNS [VarBiRel] ~ INLINE {IF br#nilBiRel AND br.class.mutability#variable THEN Complain[br, notVariable]; RETURN [[br]]}; UWBiRel: TYPE ~ RECORD [BiRel] --an unwritable BiRel--; IsUW: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [br.class.mutability#variable]}; AsUW: PROC [br: BiRel] RETURNS [UWBiRel] ~ INLINE {IF br#nilBiRel AND br.class.mutability=variable THEN Complain[br, writeable]; RETURN [[br]]}; ConstBiRel: TYPE ~ RECORD [UWBiRel] --a constant BiRel--; IsConst: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [br.class.mutability=constant]}; AsConst: PROC [br: BiRel] RETURNS [ConstBiRel] ~ INLINE {IF br#nilBiRel AND br.class.mutability#constant THEN Complain[br, notConstant]; RETURN [[[br]]]}; Function: TYPE ~ BiRel --a BiRel that doesn't have two pairs with equal left sides--; VarFunction: TYPE ~ VarBiRel; UWFunction: TYPE ~ UWBiRel; ConstFunction: TYPE ~ ConstBiRel; IsFunction: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [br.class.functional[leftToRight]]}; AsFunction: PROC [br: BiRel] RETURNS [Function] ~ INLINE {IF NOT br.class.functional[leftToRight] THEN br.Complain[narrowFault]; RETURN [br]}; InvFunction: TYPE ~ BiRel --a BiRel that doesn't have two pairs with equal right sides--; IsInvFunction: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [br.class.functional[rightToLeft]]}; AsInvFunction: PROC [br: BiRel] RETURNS [InvFunction] ~ INLINE {IF NOT br.class.functional[rightToLeft] THEN br.Complain[narrowFault]; RETURN [br]}; OneToOne: TYPE ~ BiRel --a one-to-one BiRel--; VarOneToOne: TYPE ~ VarBiRel; ConstOneToOne: TYPE ~ ConstBiRel; IsOneToOne: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [br.class.functional=ALL[TRUE]]}; AsOneToOne: PROC [br: BiRel] RETURNS [OneToOne] ~ INLINE {IF NOT br.class.functional=ALL[TRUE] THEN br.Complain[narrowFault]; RETURN [br]}; Apply: PROC [br: BiRel, v: Value, dir: Direction _ leftToRight] RETURNS [MaybeValue] ~ INLINE {RETURN br.class.Apply[br, v, dir]}; mappingNotSingleton: READONLY ROPE; InvApply: PROC [br: BiRel, v: Value] RETURNS [MaybeValue] ~ INLINE {RETURN br.class.Apply[br, v, rightToLeft]}; ApplyA: PROC [br: BiRel, v: REF ANY, dir: Direction _ leftToRight] RETURNS [MaybeValue] ~ INLINE {RETURN br.class.Apply[br, AV[v], dir]}; ApplyI: PROC [br: BiRel, v: INT, dir: Direction _ leftToRight] RETURNS [MaybeValue] ~ INLINE {RETURN br.class.Apply[br, IV[v], dir]}; InvApplyA: PROC [br: BiRel, v: REF ANY] RETURNS [MaybeValue] ~ INLINE {RETURN br.class.Apply[br, AV[v], rightToLeft]}; InvApplyI: PROC [br: BiRel, v: INT] RETURNS [MaybeValue] ~ INLINE {RETURN br.class.Apply[br, IV[v], rightToLeft]}; UpdateDecider: TYPE ~ PROC [MaybeValue] RETURNS [MaybeValue]; Update: PROC [br: BiRel, val: Value, dir: Direction, Decide: UpdateDecider] ~ INLINE {br.class.Update[br, val, dir, Decide]}; notFunctional: READONLY ROPE; --complaint raised when a caller tries an operation that requires a BiRel to be functional in a direction it is not. IntRel: TYPE ~ BiRel --where left side may only contain integers--; IsIntRel: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [QuaIntRel[br].found]}; AsIntRel: PROC [br: BiRel] RETURNS [IntRel] ~ INLINE {RETURN [QuaIntRel[br].it]}; QuaIntRel: PROC [br: BiRel] RETURNS [MaybeBiRel]; GetIntDom: PROC [br: BiRel, want: EndBools _ []] RETURNS [IntInterval]; ShiftAndClipMe: PROC [br: IntRel, shift: EINT _ zero, clip: IntInterval _ []] ~ INLINE {br.class.ShiftAndClipMe[br, shift, clip]}; Index: PROC [br, goal: IntRel, bounds: IntInterval _ [], bwd: BOOL _ FALSE] RETURNS [MaybeValue] ~ INLINE {RETURN br.class.Index[br, goal, bounds, bwd]}; ReplaceMe: PROC [br, with: IntRel, where: IntInterval] ~ INLINE {br.class.ReplaceMe[br, with, where]}; Insert: PROC [br: IntRel, val: Value, before: INT] ~ INLINE {[] _ ReplaceMe[br, CreateSingleton[[[i: 0], val], br.Spaces], [before, before-1]]}; Append: PROC [br: IntRel, val: Value] ~ INLINE {Insert[br, val, br.GetIntDom.max+1]}; AppendA: PROC [br: IntRel, val: REF ANY] ~ INLINE {Insert[br, AV[val], br.GetIntDom.max+1]}; AppendI: PROC [br: IntRel, val: INT] ~ INLINE {Insert[br, IV[val], br.GetIntDom.max+1]}; IntFn: TYPE ~ IntRel --that is Functional[leftToRight]--; ConstIntFn: TYPE ~ ConstBiRel; IsIntFn: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [QuaIntFn[br].found]}; AsIntFn: PROC [br: BiRel] RETURNS [IntFn] ~ INLINE {RETURN [QuaIntFn[br].it]}; QuaIntFn: PROC [br: BiRel] RETURNS [MaybeBiRel]; Array: TYPE ~ IntFn --whose domain is an interval--; IsArray: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [IsIntFn[br] AND br.IsDense[now, left]]}; AsArray: PROC [br: BiRel] RETURNS [Array] ~ INLINE {IF NOT (IsIntFn[br] AND br.IsDense[now, left]) THEN br.Complain[narrowFault]; RETURN [br]}; FixedArray: TYPE ~ Array --whose domain will never change--; IsFixedArray: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [IsIntFn[br] AND br.IsDense[always, left] AND br.SideFixed[left]]}; AsFixdArray: PROC [br: BiRel] RETURNS [FixedArray] ~ INLINE {IF NOT IsFixedArray[br] THEN br.Complain[narrowFault]; RETURN [br]}; Sequence: TYPE ~ Array --whose lower bound is 0--; IsSequence: PROC [br: BiRel] RETURNS [BOOL] ~ INLINE {RETURN [br.IsArray AND br.GetIntDom[].min=0]}; Automorphism: TYPE ~ BiRel--that's one-to-one, and domain = range--; Permutation: TYPE ~ Sequence--that's an Automorphism--; GradeUp: PROC [a: IntFn, o: SetBasics.Order] RETURNS [p: Permutation]; TransPermute: PROC [from: IntFn, to: Sequence, p: Permutation]; PermuteInPlace: PROC [a: Sequence, p: Permutation]; CreateEmptyBiRel: PROC [SpacePair] RETURNS [ConstBiRel]; CreateIDSubset: PROC [Set] RETURNS [BiRel]; IsIDSubset: PROC [BiRel] RETURNS [BOOL]; CreateFullIDSubset: PROC [s: Space] RETURNS [ConstOneToOne] ~ INLINE {RETURN [CreateIDSubset[CreateFullSet[s]].AsConst]}; CreateAllPairs: PROC [SpacePair] RETURNS [ConstOneToOne]; CreateSingleton: PROC [elt: Pair, spaces: SpacePair] RETURNS [ConstBiRel] ~ INLINE {RETURN [[[[GetSingletonClass[spaces], NEW [Pair _ elt]]]]]}; GetSingletonClass: PROC [spaces: SpacePair] RETURNS [BiRelClass]; NCreateSingleton: PROC [elt: Pair, spaces: SpacePair] RETURNS [ConstBiRel]; CreateConstant: PROC [bounds: Interval, val: Value, spaces: SpacePair _ [ints, refs]] RETURNS [ConstIntFn] ~ INLINE {RETURN CreateProduct[[IntervalAsSet[spaces[left], bounds], Sets.CreateSingleton[val, spaces[right]]]].AsConst}; CreateProduct: PROC [SetPair] RETURNS [BiRel]; FnFromProc: PROC [ Apply: PROC [data: REF ANY, v: Value] RETURNS [mv: MaybeValue], spaces: SpacePair _ [refs, refs], data: REF ANY _ NIL, constant, oneToOne: BOOL _ FALSE, ScanInverse: PROC [data: REF ANY, v: Value, Test: Tester] RETURNS [MaybePair] _ NIL ] RETURNS [Function]; CreateVector: PROC [bounds: IntInterval _ [0, -1], val: Value _ noValue, oneToOne, dense, domainFixed: BOOL _ FALSE, rightSpace: Space _ refs] RETURNS [IntFn]; CreateVectorCopy: PROC [of: IntFn, bounds: IntInterval _ [], oneToOne, dense, domainFixed: RelBool _ SAME, rightSpace: Space _ NIL] RETURNS [IntFn]; CreateList: PROC [vals: LOP, functional: BoolPair _ [FALSE, FALSE], spaces: SpacePair _ [refs, refs], mutability: Mutability _ variable, order: RelOrder _ [], assumeSorted: BOOL _ FALSE] RETURNS [BiRel]; HashFn: TYPE ~ VarFunction; CreateHashReln: PROC [spaces: SpacePair _ [refs, refs], functional: BoolPair _ ALL[FALSE], mappable: BoolPair _ ALL[TRUE]] RETURNS [VarBiRel]; CreateHashOTO: PROC [spaces: SpacePair _ [refs, refs]] RETURNS [VarOneToOne] ~ INLINE {RETURN CreateHashReln[spaces, ALL[TRUE]]}; CreateHashFn: PROC [spaces: SpacePair _ [refs, refs], invable: BOOL _ TRUE] RETURNS [HashFn] ~ INLINE {RETURN CreateHashReln[spaces, [TRUE, FALSE], [TRUE, invable]]}; CreateHashTable: PROC [spaces: SpacePair _ [refs, refs]] RETURNS [HashFn]; CreateHashDictionary: PROC [case: BOOL _ TRUE, right: Space _ refs, invable: BOOL _ TRUE] RETURNS [HashFn] ~ INLINE {RETURN CreateHashReln[[ropes[case], right], [TRUE, FALSE], [TRUE, invable]]}; CreateHashCopy: PROC [br: BiRel, spaces: SpacePair _ ALL[NIL], mappable: BoolPair _ ALL[FALSE]] RETURNS [HashFn]; CreateRedBlackReln: PROC [spaces: SpacePair _ [refs, refs], functional: BoolPair _ ALL[FALSE], mappable: BoolPair _ ALL[TRUE]] RETURNS [VarBiRel]; CreateRedBlackFn: PROC [spaces: SpacePair _ [refs, refs], invable: BOOL _ TRUE] RETURNS [VarBiRel] ~ INLINE {RETURN CreateRedBlackReln[spaces, [TRUE, FALSE], [TRUE, invable]]}; CreateRedBlackTable: PROC [spaces: SpacePair _ [refs, refs]] RETURNS [VarBiRel]; CreateRedBlackDictionary: PROC [case: BOOL _ TRUE, right: Space _ refs, invable: BOOL _ TRUE] RETURNS [VarBiRel] ~ INLINE {RETURN CreateRedBlackReln[[ropes[case], right], [TRUE, FALSE], [TRUE, invable]]}; CreateFromHalves: PROC [spaces: SpacePair _ [refs, refs], functional: BoolPair _ ALL[FALSE], halves: HalfPair] RETURNS [VarBiRel]; HalfPair: TYPE ~ ARRAY Direction OF Half; Half: TYPE ~ RECORD [ class: HalfClass _ NIL, fn: Function _ nilBiRel]; HalfClass: TYPE ~ REF HalfClassPrivate; HalfClassPrivate: TYPE ~ RECORD [ CreateSet: PROC [Space, REF ANY] RETURNS [VarSet], setShouldScan: PACKED ARRAY Sets.RelOrder OF BOOL, setCreateData: REF ANY _ NIL ]; GenCreate: PROC [spaces: SpacePair _ [refs, refs], functional: BoolPair _ ALL[FALSE], mappable: BoolPair _ ALL[TRUE], hints: HintPair _ ALL[[]]] RETURNS [VarBiRel]; GenCopy: PROC [br: BiRel, spaces: SpacePair _ ALL[NIL], mappable: BoolPair _ ALL[FALSE], hints: HintPair _ ALL[[]]] RETURNS [VarBiRel]; HintPair: TYPE ~ ARRAY Direction OF Hint; Hint: TYPE ~ RECORD [fn, set: HintPart _ []]; HintPart: TYPE ~ RECORD [class: ATOM _ NIL, details: Details _ NIL]; Details: TYPE ~ LIST OF Detail; Detail: TYPE ~ RECORD [key: ATOM, val: REF ANY]; Union: PROC [a, b: BiRel, disjoint: BOOL _ FALSE, ro: RelOrder _ [], functional: BoolPair _ ALL[FALSE]] RETURNS [UWBiRel]; Intersection: PROC [BiRel, BiRel] RETURNS [UWBiRel]; Restriction: PROC [br: BiRel, sets: SetPair, functional: BoolPair _ ALL[FALSE]] RETURNS [UWBiRel]; Difference: PROC [BiRel, BiRel] RETURNS [UWBiRel]; SymmetricDifference: PROC [a, b: BiRel] RETURNS [c: UWBiRel]; Negate: PROC [BiRel] RETURNS [BiRel]; Compose: PROC [left, right: BiRel, restricts: ARRAY Side OF BOOL _ [TRUE, TRUE]] RETURNS [BiRel]; TransitiveFnClosure: PUBLIC PROC [base: Function, acyclic: BOOL _ FALSE] RETURNS [Function]; Invert: PROC [BiRel] RETURNS [BiRel]; Collect: PROC [u: BiRel, side: Side _ right] RETURNS [c: Function]; UnCollect: PROC [c: Function, side: Side _ right] RETURNS [u: BiRel]; Replace: PROC [br, with: IntRel, where: IntInterval] RETURNS [IntRel]; ShiftAndClip: PROC [br: IntRel, shift: EINT _ zero, clip: IntInterval _ []] RETURNS [IntRel]; CreateShiftAndClipper: PROC [shift: EINT _ zero, clip: IntInterval _ []] RETURNS [ConstOneToOne]; Shift: PROC [br: IntRel, shift: EINT] RETURNS [IntRel] ~ INLINE {RETURN ShiftAndClip[br, shift]}; Subseq: PROC [br: IntRel, bounds: IntInterval] RETURNS [IntRel] ~ INLINE {RETURN ShiftAndClip[br, IE[bounds.min].Neg, bounds]}; ImplementSetBySequence: PROC [seq: Sequence, addat: SeqAddPlace, closeGaps: BOOL] RETURNS [Set]; SeqAddPlace: TYPE ~ {front, back}; ImplementSetByIDSubset: PROC [ids: BiRel] RETURNS [Set]; EnumSeqOfSet: PROC [set: Set, ro: Sets.RelOrder _ no] RETURNS [Sequence]; BiRelClass: TYPE ~ REF BiRelClassPrivate; BiRelClassPrivate: TYPE ~ MONITORED RECORD [ Primitive: PROC [br: BiRel, op: ATOM, arg1, arg2: REF ANY _ NIL] RETURNS [PrimitiveAnswer] _ NIL, AsSet: PROC [br: BiRel, ro: RelOrder] RETURNS [Set--of REF Pair--] _ NIL, HasPair: PROC [br: BiRel, pair: Pair] RETURNS [BOOL] _ NIL, Image: PROC [br: BiRel, set: Set, dir: Direction] RETURNS [Set] _ NIL, Apply: PROC [br: BiRel, v: Value, dir: Direction] RETURNS [MaybeValue] _ NIL, ScanRestriction: PROC [br: BiRel, sets: SetPair, Test: Tester, ro: RelOrder] RETURNS [MaybePair] _ NIL, GetOne: PROC [br: BiRel, remove: BOOL, ro: RelOrder] RETURNS [MaybePair] _ NIL, Get3: PROC [br: BiRel, pair: Pair, ro: RelOrder, want: TripleBool] RETURNS [TripleMaybePair] _ NIL, Index: PROC [br, goal: IntRel, bounds: IntInterval, bwd: BOOL] RETURNS [MaybeValue] _ NIL, RestrictionSize: PROC [br: BiRel, sets: SetPair, limit: EINT] RETURNS [EINT] _ NIL, GetBounds: PROC [br: BiRel, want: EndBools, ro: RelOrder] RETURNS [MaybePairInterval] _ NIL, Copy: PROC [br: BiRel] RETURNS [VarBiRel] _ NIL, Insulate: PROC [br: BiRel] RETURNS [UWBiRel] _ NIL, ValueOf: PROC [br: BiRel] RETURNS [ConstBiRel] _ NIL, Freeze: PROC [br: BiRel] RETURNS [ConstBiRel] _ NIL, Thaw: PROC [br: BiRel] _ NIL, SetOn: PROC [br: BiRel, side: Side] RETURNS [UWSet] _ NIL, CurSetOn: PROC [br: BiRel, side: Side] RETURNS [ConstSet] _ NIL, AddPair: PROC [br: BiRel, pair: Pair, if: IfHadPair] RETURNS [had: HadPair] _ NIL, AddSet: PROC [br, other: BiRel, if: IfHadPair] RETURNS [some: HadSetPair] _ NIL, Swap: PROC [br: BiRel, a, b: Value, side: Side] _ NIL, RemPair: PROC [br: BiRel, pair: Pair] RETURNS [had: HadPair] _ NIL, RemSet: PROC [br, other: BiRel] RETURNS [some: HadSetPair] _ NIL, Update: PROC [br: BiRel, val: Value, dir: Direction, Decide: UpdateDecider] _ NIL, Delete: PROC [br: BiRel, val: Value, side: Side] RETURNS [hadSome: BOOL] _ NIL, DeleteSet: PROC [br: BiRel, set: Set, side: Side] RETURNS [had: SomeAll] _ NIL, ReplaceMe: PROC [br, with: IntRel, where: IntInterval] _ NIL, ShiftAndClipMe: PROC [br: BiRel, shift: EINT, clip: IntInterval] _ NIL, Spaces: PROC [br: BiRel] RETURNS [SpacePair] _, IsDense: PROC [br: BiRel, when: When, side: Side] RETURNS [BOOL] _ NIL, SideFixed: PROC [br: BiRel, side: Side] RETURNS [BOOL] _ NIL, functional: BoolPair _ [FALSE, FALSE], mutability: Mutability _ variable, other: Atom.PropList _ NIL, --the canonical expansion slot data: REF ANY _ NIL ]; CreateClass: PROC [cp: BiRelClassPrivate, dirable: BoolPair _ [TRUE, FALSE], restrictable: RestrictabilityPair _ ALL[none]] RETURNS [BiRelClass]; RestrictabilityPair: TYPE ~ ARRAY Direction OF Restrictability; Restrictability: TYPE ~ {none, tiny, any}; DefaultAsSet: PROC [br: BiRel, ro: RelOrder] RETURNS [Set--of REF Pair--]; DefaultHasPair: PROC [br: BiRel, pair: Pair] RETURNS [BOOL]; DefaultImage: PROC [br: BiRel, set: Set, dir: Direction] RETURNS [Set]; DefaultApply: PROC [br: BiRel, v: Value, dir: Direction] RETURNS [MaybeValue]; DefaultScanRestriction: PROC [br: BiRel, sets: SetPair, Test: Tester, ro: RelOrder] RETURNS [MaybePair]; DefaultGetOne: PROC [br: BiRel, remove: BOOL, ro: RelOrder] RETURNS [MaybePair]; DefaultGet3: PROC [br: BiRel, pair: Pair, ro: RelOrder, want: TripleBool] RETURNS [TripleMaybePair]; DefaultIndex: PROC [br, goal: IntRel, bounds: IntInterval, bwd: BOOL] RETURNS [MaybeValue]; DefaultRestrictionSize: PROC [br: BiRel, sets: SetPair, limit: EINT] RETURNS [EINT]; DefaultGetBounds: PROC [br: BiRel, want: EndBools, ro: RelOrder] RETURNS [MaybePairInterval]; DefaultCopy: PROC [br: BiRel] RETURNS [VarBiRel]; DefaultInsulate: PROC [br: BiRel] RETURNS [UWBiRel]; DefaultValueOf: PROC [br: BiRel] RETURNS [ConstBiRel]; DefaultFreeze: PROC [br: BiRel] RETURNS [ConstBiRel]; DefaultThaw: PROC [br: BiRel]; DefaultSetOn: PROC [br: BiRel, side: Side] RETURNS [UWSet]; DefaultCurSetOn: PROC [br: BiRel, side: Side] RETURNS [ConstSet]; DefaultAddPair: PROC [br: BiRel, pair: Pair, if: IfHadPair] RETURNS [had: HadPair]; DefaultAddSet: PROC [br, other: BiRel, if: IfHadPair] RETURNS [some: HadSetPair]; DefaultSwap: PROC [br: BiRel, a, b: Value, side: Side]; DefaultRemPair: PROC [br: BiRel, pair: Pair] RETURNS [had: HadPair]; DefaultRemSet: PROC [br, other: BiRel] RETURNS [some: HadSetPair]; DefaultUpdate: PROC [br: BiRel, val: Value, dir: Direction, Decide: UpdateDecider]; DefaultDelete: PROC [br: BiRel, val: Value, side: Side] RETURNS [hadSome: BOOL]; DefaultDeleteSet: PROC [br: BiRel, set: Set, side: Side] RETURNS [had: SomeAll]; DefaultReplaceMe: PROC [br, with: IntRel, where: IntInterval]; DefaultShiftAndClipMe: PROC [br: BiRel, shift: EINT, clip: IntInterval]; DefaultIsDense: PROC [br: BiRel, when: When, side: Side] RETURNS [BOOL]; DefaultSideFixed: PROC [br: BiRel, side: Side] RETURNS [BOOL]; HasByApplyL2R: PROC [br: BiRel, pair: Pair] RETURNS [BOOL]; ApplyByUpdate: PROC [br: BiRel, v: Value, dir: Direction] RETURNS [MaybeValue]; UpdateBiRelClassOther: PROC [class: BiRelClass, Update: PROC [Atom.PropList] RETURNS [Atom.PropList]]; QualityOf: PROC [br: BiRel, op: ATOM, arg1, arg2, arg3, arg4: REF ANY _ NIL] RETURNS [ImplQuality]; RefBiRel: TYPE ~ REF BiRel; RefSetPair: TYPE ~ REF SetPair; refNilSets: READONLY RefSetPair; ToSide: PROC [arg: REF ANY, default: Side _ left] RETURNS [Side]; ToDir: PROC [arg: REF ANY, default: Direction _ leftToRight] RETURNS [Direction]; ToBiRel: PROC [arg: REF ANY] RETURNS [RefBiRel]; ToSets: PROC [arg: REF ANY, default: RefSetPair _ refNilSets] RETURNS [RefSetPair]; ToRO: PROC [arg: REF ANY, default: RelOrder _ []] RETURNS [RelOrder]; FromSide: PROC [side: Side] RETURNS [ATOM] ~ INLINE {RETURN [IF side=left THEN $left ELSE $right]}; FromDir: PROC [dir: Direction] RETURNS [ATOM] ~ INLINE {RETURN [IF dir=leftToRight THEN $leftToRight ELSE $rightToLeft]}; FakeSingleton: PROC [sp: SpacePair] RETURNS [ConstBiRel] ~ INLINE {RETURN CreateSingleton[noPair, sp]}; FakeRefSingleton: PROC [sp: SpacePair] RETURNS [RefBiRel] ~ INLINE {RETURN CreateSingleton[noPair, sp].Refify}; FromSets: PROC [sp: SetPair] RETURNS [RefSetPair]; FromRO: PROC [ro: RelOrder] RETURNS [ATOM]; Can: PROC [br: BiRel, op: ATOM, arg1, arg2, arg3, arg4: REF ANY _ NIL] RETURNS [BOOL] ~ INLINE {RETURN [QualityOf[br, op, arg1, arg2, arg3, arg4]#cant]}; GoodImpl: PROC [br: BiRel, op: ATOM, arg1, arg2, arg3, arg4: REF ANY _ NIL] RETURNS [BOOL] ~ INLINE {RETURN [QualityOf[br, op, arg1, arg2, arg3, arg4]>=goodDefault]}; Primitive: PROC [br: BiRel, op: ATOM, arg1, arg2: REF ANY _ NIL] RETURNS [BOOL]; Complain: PROC [br: BiRel, msg: ROPE, args: LOV _ NIL] ~ INLINE {Error[msg, CONS[AV[br.Refify], args]]}; MaybeBiRel: TYPE ~ RECORD [found: BOOL, it: BiRel]; }. BiRels.Mesa Last tweaked by Mike Spreitzer on March 4, 1988 4:57:29 pm PST Random Old Stuff Binary Relations (i.e., Sets of Pairs) A binary relation (i.e., a set of Pairs), or a variable such. Good for calling from the interpreter. Operations on BiRels Raised when a BiRel is asked to perform an operation it can't. The ordering of the space of the result respects the relative order given. For leftToRight, the result is henceforth the things that are on the right sides of pairs in br that have an element of set on their left side. Also, set may be nilSet; Image[br, nilSet, dir] = SetOn[br, Dest[dir]]. The result tracks changes to br, and changes to the result change br (in any one of the possible ways). The image of a singleton. = NOT br.Mapping[v, dir].Empty[], but the following expression stands a chance of not doing any allocations. The enumeration order respects the ordering specified by the ro argument relative to the BiRel's spaces. That is, if ro says p1 < p2, then p1 is enumerated before p2; if ro says p1 = p2, they may be enumerated in either order. Enumerates those pairs such that pair[side] is in set. If one of the restricting sets is nilSet, that means don't restrict. result is (if bwd then greatest else least) solution in bounds to: br[i]=v AND goal.HasMember[v]; if no such solution, result.found=FALSE and result.it is unrestricted. Implies br.SetOn[side].IsDense, now or forever, as requested. SideFixed[br, side] => br.SetOn[side] won't change. May also cause deletions in order to preserve functionality. Like AddPair, with the expectation that the pair is new. Equivalent to a series of AddPairs. some[n][dir] iff some AddPair[..][dir]=n. Same as AddSet[if: addIfNew], and then in functional directions d insist that some[d][same] = some[d][different] = FALSE. side=left => br after HasPair[[a, v]] iff br before HasPair[[b, v]], and so on. Equivalent to a bunch of RemPairs. Remove pair(s) with equivalent values on the given side. hadSome tells whether there were any. Every BiRel knows its spaces. Returns a collection of the elements on the given side of the pairs of br. Result tracks changes to br. Returns the current value, and thus does not track changes to br. Functional[br][leftToRight] => br can't have two pairs with equivalent left Values and non-equivalent right Values. A x in bounds[left], y in bounds[right] : in a W in b. More Special Cases of Sets Special Cases of BiRels Error raised if mapping bigger than 1. Returns noMaybe if mapping empty. Applicable only to BiRels declared functional in the given direction. new[i+shift, v] iff (old[i, v] AND i in clip AND i+shift in []). result is (if bwd then greatest else least) solution in bounds to: Equal[Shift[br, -result.i], goal, goal.bounds] (or, equivelently, Equal[br, Shift[goal, result.i], Shift[goal.bounds, result.i]]); if no such solution, result.found=FALSE and result.val is unrestricted. Let clip=with.GetIntDom in: new[i, v] iff old[i, v] & i < where.min, or with[i-where.min+clip.min, v] & where.min <= i < where.min+clip.Length, or old[i-clip.Length+where.Length, v] & where.min+clip.Length <= i. Only current value of with is used. i < j g a[p[i]] < a[p[j]]. for each [new, old] in p: to[new] _ from[old]. Some Implementations of BiRels Like CreateVector, but the function is initialized from the given one, subject to the given bounds. Giving rightSpace=NIL means to use the original's. (functional[dir] OR mappable[dir]) tells whether the result can Image in direction dir. Not invable. NIL space means use the same space as the given BiRel. Can map in direction d iff mappable[d] OR functional[d]. Implements a BiRel by a function in each required direction, whose range is a set if the whole is not functional in that direction. Short for generic, or general, create; take your pick. Actually, it's not completely general --- it will only use implementations from a fixed repertoire (which I am not stupid enough to document in this interface). The hints are where the caller can partially specify the implementation. As an example, the following call might duplicate the functionality of CreateHashReln: GenCreate[spaces, functional, mappable, ALL[[[$Hash], [$Hash]]]]. The following use a standard implementation. The result tracks changes to the arguments, if any. Result may duplicate iff any argument may. The result is only as functional as the caller guarantees. The caller may assert, through the functional argument, that the restriction is more functional than the base. restricts[left]=FALSE means caller is guaranteeing that henceforth SetOn[right, left] is included in SetOn[left, right]. Left and right spaces of base must be the same. If acyclic, caller is guaranteeing there are no cycles in the base function. When side=right, c[l, {r | u[l, r]}] OR MappingSize[c, l]=0 AND MappingSize[u, l]=0. When side=right, c is function yielding sets, and u[l, r] iff r in c[l]. result[i+shift, v] iff (br[i, v] AND i in clip AND i+shift in []). Result has pair [i, i+shift] when i IN clip AND i+shift IN [INT.FIRST..INT.LAST]. result[i+shift, v] iff br[i, v]. ids is one-to-one (but it doesn't have to be Functional[][rightToLeft], which can save work). ith element of result is ith element enumerated by set. Implementing BiRels The only part that may vary is the other, and that must be accessed through the update procedure below. NIL procs mean the implementor declines to implement the proc; NIL fields get filled in with default procedures that compute with provided fields. Iff Primitive is elided, `bkwdable' and `dirable' are taken into consideration when constructing Primitive. none => can't handle any restriction. tine => can handle restriction to obviously empty sets or singletons. any => can handle any restriction. Asking About a BiRel's Implementation Use this to investigate what operations a BiRel supports, and how well it does so. The quality depends on the BiRel, the operation, and certain arguments. Those arguments are indicated to QualityOf as arg1, arg2, and so on. An enumerated value is passed by an ATOM whose name is the name of the value; a RelOrder is passed by a coding indicated below; an other non-ref kind of value is passed as a REF to itself. The op is the name of a procedure in this interface (other than QualityOf and derivatives) that calls class procedures. Arguments that are passed are: Sets; BiRels; Directions; Sides; RelOrders; bwd, want*: BOOL; EndBools; Interval; limit: EINT; SetPairs; When. Arguments not passed are: Values; Pairs; callback procedures; remove: BOOL; IntInterval; IfHadPair. e.g.: FromRO[[[no, Bwd], left]] = $leftNoBwd Other Random New Stuff Ê(´– "cedar" style˜code™ Kšœ>™>—K˜KšÏk œ.œ ˜EK˜šÏnœœ ˜Kšœ)˜0Kšœœžœ˜<—head™Kšœœ œ˜K˜Kšœœ˜Kšœ œ˜$Kšœ œ˜*K˜Kšœœ ˜Kšœ œ˜!Kšœœ ˜K˜Kšœœ˜Kšœœ˜Kšœœœœ˜Kšœ œ˜(Kšœ œ ˜ Kšœœ˜4Kšœœ!˜8Kšœœ˜2Kšœœ˜Kšœ œ˜$Kšœ œ˜*Kšœœ˜ Kšœ œ˜(Kšœ-˜-Kšœ+˜+Kšœ+˜+Kšœ œ˜&Kšœ œ˜(Kšœ œ˜$Kšœœ˜.Kšœ œ˜&Kšœœ˜0Kšœ(˜(Kšœ(˜(Kšœ*˜*Kšœ*˜*Kšœ œ˜(—šœ&™&š œœœœœ˜8KšœÏzœŸœ1™=—K˜š ž œœœœœ ˜CK™&—K˜Kšœœœ˜Kšœ œ˜K˜š žœœœœœ˜)Kšœœœœœœœœ ˜G—šžœœ œ ˜+Kšœœœœ˜%——šœ™šžœœ ˜K™>—K˜šžœœœÏcœ˜BK™JKšœœœ˜)—K˜šžœœœœ˜4Kšœœœ˜-—K˜š žœœœœœœ˜—šžœœœ œœœœ˜AKš œœœœœ ˜>—š žœœœœœ˜8Kš œœœœœ ˜>—K˜šžœœ5œ˜MKšœÁ™ÁKšœœœ˜/—K˜šžœœ5œ˜OKšœ™KšœœœM˜]—K˜š žœœœœ œ˜RKšœœœ)œ&˜a—K˜šžœœœ œ˜NKšœœœ)œ&˜a—K˜šž œœ5œœ˜SK™lKšœœœr˜œ—K˜š žœœœœ œœ˜RKšœœœCœ1˜ —š žœœœ œœ˜NKšœœœCœ1˜ —K˜šž œœ žœœ˜EKšœ=Ïeœ7¡œ3¡œ6™ã—K˜Kšžœœ žœœœœœœ˜NKšžœœ žœœœœœ˜JKš žœœ žœœœœ˜FK˜Kš œœœœœ˜*Kšž œ œ˜%K˜šžœœ žœœ ˜KKšœœœ-˜=K˜—Kšžœœžœœ@˜xK˜šžœœžœœ?˜yKšœœ[˜c—K˜šžœœžœœ/˜qK™6—K˜Kšž œœžœEœ ˜ƒK˜šž œœžœEœ ˜„KšœœœR˜b—K˜šžœœ!žœœ ˜jKšœ"¡œ™DKšœœœ/˜?—K˜šžœœžœ0œ ˜wKšœœœ>˜N—K˜šž œœžœ+œ˜fKšœœœ8˜H—K˜KšžœœžœGœ˜ŽK˜Kš œœœœœœ˜KKšœœœ œ˜;K˜KšžœœžœLœ ˜™K˜Kš œœœœ œœ ˜XK˜šžœœœœ ˜HKšœœœ"˜2—šžœœ œ ˜>Kšœœœœ˜1—šžœœ œ ˜œ˜hKšœœœ#˜3—K˜šž œœ œ ˜3Kšœœœ˜(—K˜šžœœ œ ˜)Kšœœœ˜$—K˜šžœœ œ ˜,Kšœœœ˜(—K˜šžœœ œ ˜.Kšœœœ˜'—K˜šžœœ œ ˜-Kšœœœ˜&—K˜šžœœ ˜Kšœœ˜—K˜Kšžœœ$œ˜BK˜šžœœ4œ˜WK™K˜Kšž œœ œ œ˜HK˜Kšž œœœœ œœœœ˜eK˜Kšž œœœœœœœœ˜f—™šž œœ œœ˜*Kšœœœ"˜2—šž œœ œ˜+Kšœœœ˜(—šž œœ œ ˜1šœœ˜ Kšœœ˜ Kšœ œœ˜Kšœ/˜/Kšœœœœœœœ˜M———™Kšœ œœ  œ˜5šžœœ œœ˜&Kšœœœ!˜1—šžœœ œ ˜*Kš œœœ œœœ ˜i—K˜Kšœ œœ  œ˜7šžœœ œœ˜%Kšœœœ!˜1—šžœœ œ ˜(Kš œœœ œœœ ˜g—K˜Kšœ œœ  œ˜9šžœœ œœ˜(Kšœœœ!˜1—šžœœ œ ˜.Kš œœœ œœœ ˜k—K˜Kšœ œ  =œ˜UKšœ œ ˜Kšœ œ ˜Kšœœ˜!šž œœ œœ˜+Kšœœœ%˜5—šž œœ œ ˜/Kš œœœœ"œœ˜^—K˜Kšœ œ  >œ˜Yšž œœ œœ˜.Kšœœœ%˜5—šž œœ œ˜5Kš œœœœ"œœ˜^—K˜Kšœ œ  œ˜.Kšœ œ ˜Kšœœ˜!šž œœ œœ˜+Kš œœœœœ˜2—šž œœ œ ˜/Kšœœœœœœœœ˜[—K˜šžœœ5œ ˜TKšœH™HKšœœœ˜-Kšœœœ˜#—K˜šžœœœ ˜9Kšœœœ%˜5—K˜š žœœœœ œ ˜WKšœœœœ ˜1—K˜šžœœœ œ ˜SKšœœœœ ˜1—K˜š ž œœœœœ ˜Kšžœœœ˜HKšžœœ%œœ˜HKšžœœœœ˜>K˜Kšž œœœœ˜;Kšž œœ'œ˜OK˜Kš žœœžœœœ˜f—šœ%™%šž œœœœœœœ˜cKšœ˜™˜KšœWœœ™Kšœc™c—K˜Kšœ œœ˜Kšœ œœ ˜Kšœ œ ˜ K˜Kš žœœœœœ˜AKš žœœœœ$œ ˜QKš žœœœœœ ˜0Kš žœœœœ$œ˜SKš žœœœœœ ˜Ešžœœœœ˜*Kš œœœœ œœ ˜8—šžœœœœ˜-Kš œœœœœœ˜K—šž œœœ ˜8Kšœœœ˜.—šžœœœ ˜9Kšœœœ%˜5—Kšžœœœ˜2šžœœœœ˜+K™,—K˜šžœœœœœœœœ˜UKšœœœ3˜C—K˜šžœœœœœœœœ˜ZKšœœœ;˜K—K˜Kšž œœœœœœœœ˜PK˜—™š žœœœœœ˜6Kšœœ œœ˜1—K˜Kšœ œœ œ ˜3—L˜—…—|¾î