Operations on BiRels
Cant:
ERROR [br: BiRel];
Raised when a BiRel is asked to perform an operation it can't.
AsSet:
PROC [br: BiRel, ro: RelOrder]
RETURNS [Set
--of REF Pair--]
The ordering of the space of the result respects the relative order given.
~ 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]
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. The result tracks changes to br, and changes to the result change br (in any one of the possible ways).
~ INLINE {RETURN br.class.Image[br, set, dir]};
Mapping:
PROC [br: BiRel, v: Value, dir: Direction ← leftToRight]
RETURNS [Set]
The image of a singleton.
~ 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]};
Enumerate:
PROC [br: BiRel,
Consume:
PROC [Pair], ro: RelOrder ← []];
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.
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 ← []];
Enumerates those pairs such that pair[side] is in set.
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]
If one of the restricting sets is nilSet, that means don't restrict.
~ 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 ← left, bwd:
BOOL ←
FALSE]
RETURNS [MaybePair]
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.
~ INLINE {RETURN br.ScanRestriction[ConsSets[side, IntervalAsSet[br.Spaces[][side], bounds], goal], AcceptAny, ConsRelOrder[side, IF bwd THEN bwd ELSE fwd]]};
Lookup:
PROC [br: BiRel, goal: Value, bounds: Interval ← fullInterval, side: Side ← left, 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]
Implies br.SetOn[side].IsDense, now or forever, as requested.
~ 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]
SideFixed[br, side] => br.SetOn[side] won't change.
~ 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]
May also cause deletions in order to preserve functionality.
~ 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];
Like AddPair, with the expectation that the pair is new.
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]
Equivalent to a series of AddPairs. some[n][dir] iff some AddPair[..][dir]=n.
~ INLINE {RETURN br.class.AddSet[br, other, if]};
AddNewSet:
PROC [br, other: BiRel];
Same as AddSet[if: addIfNew], and then in functional directions d insist that some[d][same] = some[d][different] = FALSE.
Swap:
PROC [br: BiRel, a, b: Value, side: Side ← left]
side=left => br after HasPair[[a, v]] iff br before HasPair[[b, v]], and so on.
~ 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];
RemSet:
PROC [br, other: BiRel]
RETURNS [some: HadSetPair]
Equivalent to a bunch of RemPairs.
~ 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]
Remove pair(s) with equivalent values on the given side. hadSome tells whether there were any.
~ 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]};
Spaces:
PROC [br: BiRel]
RETURNS [SpacePair]
Every BiRel knows its spaces.
~ INLINE {RETURN br.class.Spaces[br]};
SetOn:
PROC [br: BiRel, side: Side]
RETURNS [UWSet]
Returns a collection of the elements on the given side of the pairs of br. Result tracks changes to br.
~ INLINE {RETURN [br.class.SetOn[br, side]]};
CurSetOn:
PROC [br: BiRel, side: Side]
RETURNS [ConstSet]
Returns the current value, and thus does not track changes to br.
~ INLINE {RETURN br.class.CurSetOn[br, side]};
Functional:
PROC [br: BiRel]
RETURNS [BoolPair]
Functional[br][leftToRight] => br can't have two pairs with equivalent left Values and non-equivalent right Values.
~ INLINE {RETURN [br.class.functional]};
Equal:
PROC [a, b: BiRel, bounds: SetPair ← []]
RETURNS [
BOOL];