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[