BiRelDefaults.Mesa
Last tweaked by Mike Spreitzer on December 14, 1987 2:04:50 pm PST
 
DIRECTORY AbSets, Atom, BiRelBasics, BiRels, BiRelsPrivate, IntStuff, List, SetBasics;
BiRelDefaults: 
CEDAR 
PROGRAM
IMPORTS AbSets, BiRelBasics, BiRels, BiRelsPrivate, IntStuff, SetBasics
EXPORTS BiRels
=
 
BEGIN OPEN IntStuff, SetBasics, Sets:AbSets, Sets, BiRelBasics, BiRels, BiRelsPrivate;
DefaultHasPair: 
PUBLIC 
PROC [br: BiRel, pair: Pair] 
RETURNS [
BOOL] ~ {
spaces: SpacePair ~ br.Spaces[];
RETURN [br.ScanRestriction[[Sets.CreateSingleton[pair[left], spaces[left]], Sets.CreateSingleton[pair[right], spaces[right]]], AcceptAny].found]};
 
DefaultApply: 
PUBLIC 
PROC [br: BiRel, v: Value, dir: Direction] 
RETURNS [mv: MaybeValue ← noMaybe] ~ {
src: Side ~ Source[dir];
dst: Side ~ Dest[dir];
n: LNAT ← 0;
Test: 
PROC [pair: Pair] 
RETURNS [
BOOL] ~ {
IF (n ← n + 1) > 1 THEN br.Complain[mappingNotSingleton, LIST[v]];
TRUSTED {mv ← [TRUE, pair[dst]]};
RETURN [FALSE]};
 
[] ← br.ScanRestriction[ConsSets[src, Sets.CreateSingleton[v, br.Spaces[][src]]], Test];
RETURN};
 
ImageSize: 
PUBLIC 
PROC [br: BiRel, set: Set, dir: Direction ← leftToRight, limit: 
EINT ← lastEINT] 
RETURNS [
EINT] ~ {
easy: BOOL ~ set.GoodImpl[$Size] AND set.Size[two].Compare[two]<equal;
IF easy THEN RETURN br.RestrictionSize[ConsSets[Source[dir], set], limit];
{image: Set ~ br.Image[set, dir];
RETURN set.DefaultSize[limit]}};
 
DefaultGetOne: 
PUBLIC 
PROC [br: BiRel, remove: 
BOOL, ro: RelOrder] 
RETURNS [mp: MaybePair ← noMaybePair] ~ {
IF remove AND br.MutabilityOf[]#variable THEN br.Complain[notVariable];
IF ro.sub=ALL[no] OR br.GoodImpl[$Scan, FromRO[ro]]
THEN mp ← br.Scan[AcceptAny, ro]
ELSE {
spaces: SpacePair ~ br.Spaces[];
SeekBest: 
PROC [pair: Pair] 
RETURNS [
BOOL] ~ {
IF mp.found
THEN {IF ro.RelPCompare[spaces, pair, mp.it]=less THEN TRUSTED {mp.it ← pair}}
ELSE mp ← [TRUE, pair];
 
RETURN [FALSE]};
 
[] ← br.Scan[SeekBest];
ro ← ro};
 
IF mp.found AND remove THEN [] ← br.RemPair[mp.it];
RETURN};
 
DefaultGet3: 
PUBLIC 
PROC [br: BiRel, pair: Pair, ro: RelOrder, want: TripleBool] 
RETURNS [TripleMaybePair] ~ {
ro ← ro.CanonizeRelOrder[br.Functional];
{fq, bq, nq: ImplQuality ← br.QualityOf[$Scan, FromRO[ro]];
rro: RelOrder;
IF ro.sub # 
ALL[no] 
THEN {
bq ← br.QualityOf[$Scan, FromRO[rro ← ro.ReverseRO[]]];
nq ← br.QualityOf[$Scan]};
 
{max: ImplQuality ~ QMax[nq, QMax[fq, bq]];
spaces: SpacePair ~ br.Spaces[];
prev, same, next: MaybePair ← noMaybePair;
IF fq=max 
OR bq=max 
THEN {
bwd: BOOL ~ bq=max AND fq<max;
take: BOOL ← FALSE;
Test: 
PROC [this: Pair] 
RETURNS [pass: 
BOOL ← 
FALSE] ~ {
IF PEqual[spaces, this, pair] THEN same ← [take ← TRUE, pair]
ELSE IF take THEN pass ← TRUE
ELSE prev ← [TRUE, this];
};
 
next ← br.Scan[Test, IF bwd THEN rro ELSE ro];
IF bwd THEN RETURN [[next, same, prev]];
RETURN [[prev, same, next]]}
 
ELSE {
foundSame: BOOL ← FALSE;
Test: 
PROC [this: Pair] 
RETURNS [pass: 
BOOL ← 
FALSE] ~ {
SELECT ro.RelPCompare[spaces, this, pair] 
FROM
less => IF (NOT prev.found) OR ro.RelPCompare[spaces, this, prev.it]=greater THEN prev ← [TRUE, this];
equal => foundSame ← TRUE;
greater => IF (NOT next.found) OR ro.RelPCompare[spaces, this, next.it]=less THEN next ← [TRUE, this];
notrel => NULL;
ENDCASE => ERROR;
 
RETURN};
 
IF br.Scan[Test].found THEN ERROR;
RETURN [[prev, IF foundSame THEN [TRUE, pair] ELSE noMaybePair, next]]};
 
}}};
 
DefaultIndex: 
PUBLIC 
PROC [br, goal: IntRel, bounds: IntInterval, bwd: 
BOOL] 
RETURNS [MaybeValue] ~ {
ENABLE Cant => Cant[br];
right: Space ~ br.Spaces[][right];
brBounds: IntInterval ~ IF br.GoodImpl[$GetIntDom] THEN br.GetIntDom[] ELSE [];
goalBounds: IntInterval ~ goal.GetIntDom[];
goalLen: EINT ~ goalBounds.Length;
first: Set ~ IF goalBounds.Empty THEN nilSet ELSE goal.Mapping[[i[goalBounds.min]]];
scanBounds: IntInterval ~ Intersect[