VersionMap2Combs.Mesa
Copyright Ó 1990 by Xerox Corporation. All rights reserved.
Last tweaked by Mike Spreitzer on December 1, 1990 5:33 pm PST
DIRECTORY MorePfsNames, PFSNames, Rope, RopeParts, VersionMap2, VersionMap2Implr;
VersionMap2Combs: CEDAR PROGRAM
IMPORTS MorePfsNames, PFSNames, RopeParts, VersionMap2, VersionMap2Implr
EXPORTS VersionMap2, VersionMap2Implr
=
BEGIN OPEN MPfsN:MorePfsNames, VersionMap2, VersionMap2Implr;
notClass: MapClass ~ FillinDefaults[FALSE, readonly, [
MMutability: NotMMutability,
Has: NotHas,
AddTuple: NotAddTuple,
AddMap: NotAddMap,
RemTuple: NotRemTuple,
RemMap: NotRemMap,
Negate: NotNegate,
IsNegation: NotIsNegation,
data: NIL]];
DefaultNegate: PUBLIC PROC [map: Map] RETURNS [Map]
~ {RETURN [[notClass, map.Refify[]]]};
DefaultIsNegation: PUBLIC PROC [map: Map] RETURNS [MaybeMap]
~ {RETURN [[FALSE, nullMap]]};
NotFunctional: PROC [map: Map] RETURNS [BOOL] ~ {RETURN [FALSE]};
NotMMutability: PROC [map: Map] RETURNS [Mutability] ~ {
sub: REF Map ~ NARROW[map.data];
RETURN sub^.MMutability[]};
NotHas: PROC [map: Map, elt: VersionTuple] RETURNS [BOOL] ~ {
sub: REF Map ~ NARROW[map.data];
RETURN [NOT sub^.Has[elt]]};
NotAddTuple: PROC [map: Map, t: VersionTuple, if: IfHads] RETURNS [had: Hads] ~ {
sub: REF Map ~ NARROW[map.data];
[] ← sub^.RemTuple[t];
RETURN [ALL[none]]};
NotAddMap: PROC [map, other: Map, if: IfHads] RETURNS [some: HadSets] ~ {
sub: REF Map ~ NARROW[map.data];
[] ← sub^.RemMap[other];
RETURN [ALL[ALL[FALSE]]]};
NotRemTuple: PROC [map: Map, t: VersionTuple] RETURNS [had: Hads] ~ {
sub: REF Map ~ NARROW[map.data];
[] ← sub^.AddTuple[t];
RETURN [ALL[none]]};
NotRemMap: PROC [map, other: Map] RETURNS [some: HadSets] ~ {
sub: REF Map ~ NARROW[map.data];
[] ← sub^.AddMap[other];
RETURN [ALL[ALL[FALSE]]]};
NotNegate: PROC [map: Map] RETURNS [Map] ~ {
sub: REF Map ~ NARROW[map.data];
RETURN [sub^]};
NotIsNegation: PROC [map: Map] RETURNS [MaybeMap] ~ {
sub: REF Map ~ NARROW[map.data];
RETURN [[TRUE, sub^]]};
Binary: TYPE ~ REF BinaryPrivate;
BinaryPrivate: TYPE ~ RECORD [a, b: Map, op: {and, or}, test: UnionTest, ordered: BOOL];
andClass: MapClass ~ FillinDefaults[FALSE, readonly, [
Functional: AndFunctional,
MMutability: BinMMutability,
Has: AndHas,
Scan: AndScan,
CreateGenerator: AndCreateGenerator,
Size: SizeByScan,
Negate: AndNegate,
IsIntersection: AndIsIntersection,
data: NIL]];
orClass: MapClass ~ FillinDefaults[FALSE, readonly, [
MMutability: BinMMutability,
Has: OrHas,
Scan: OrScan,
CreateGenerator: OrCreateGenerator,
Size: SizeByScan,
Negate: OrNegate,
IsUnion: OrIsUnion,
data: NIL]];
DefaultIntersect: PUBLIC PROC [map, other: Map] RETURNS [Map] ~ {
IF map=aFull THEN RETURN [other];
IF other=aFull THEN RETURN [map];
IF map=anEmpty OR other=anEmpty THEN RETURN [anEmpty];
{b: Binary ~ NEW [BinaryPrivate ← [map, other, and, other, FALSE]];
RETURN [[andClass, b]]}};
DefaultIsIntersection: PUBLIC PROC [map: Map] RETURNS [Maybe2Maps] ~ {
RETURN [[FALSE, nullMap, nullMap]]};
DefaultUnion: PUBLIC PROC [map, other: Map, test: UnionTest, ordered: BOOL] RETURNS [Map] ~ {
IF map=anEmpty THEN RETURN [other];
IF other=anEmpty THEN RETURN [map];
IF map=aFull OR other=aFull THEN RETURN [anEmpty];
{b: Binary ~ NEW [BinaryPrivate ← [map, other, or, test, ordered]];
RETURN [[orClass, b]]}};
DefaultIsUnion: PUBLIC PROC [map: Map] RETURNS [Maybe2Maps] ~ {
RETURN [[FALSE, nullMap, nullMap]]};
DefaultDifference: PUBLIC PROC [map, other: Map] RETURNS [Map] ~ {
RETURN map.Intersect[other.Negate[]]};
DefaultIsDifference: PUBLIC PROC [map: Map] RETURNS [Maybe2Maps] ~ {
m1: Maybe2Maps ~ map.IsIntersection[];
m2: MaybeMap;
IF NOT m1.found THEN RETURN [m1];
IF (m2 ← m1.other.IsNegation).found THEN RETURN [[TRUE, m1.map, m2.it]];
IF (m2 ← m1.map.IsNegation).found THEN RETURN [[TRUE, m1.other, m2.it]];
RETURN [[FALSE, nullMap, nullMap]]};
DefaultSymmetricDifference: PUBLIC PROC [map, other: Map] RETURNS [Map] ~ {
d1: Map ~ map.Difference[other];
d2: Map ~ other.Difference[map];
RETURN d1.Union[d2]};
DefaultIsSymmetricDifference: PUBLIC PROC [map: Map] RETURNS [Maybe2Maps] ~ {
m1: Maybe2Maps ~ map.IsUnion[];
IF NOT m1.found THEN RETURN [m1];
{m12: Maybe2Maps ~ m1.map.IsDifference[];
m21: Maybe2Maps ~ m1.other.IsDifference[];
IF m12.found AND m21.found AND m12.map=m21.other AND m12.other=m21.map THEN RETURN [m12];
RETURN [[FALSE, nullMap, nullMap]]}};
AndFunctional: PROC [map: Map] RETURNS [BOOL] ~ {
b: Binary ~ NARROW[map.data];
RETURN [b.a.Functional[] OR b.b.Functional[]]};
BinMMutability: PROC [map: Map] RETURNS [Mutability] ~ {
b: Binary ~ NARROW[map.data];
RETURN [MIN[readonly, MIN[b.a.MMutability[], b.b.MMutability[]]]]};
AndHas: PROC [map: Map, elt: VersionTuple] RETURNS [BOOL] ~ {
b: Binary ~ NARROW[map.data];
RETURN [b.a.Has[elt] AND b.b.Has[elt]]};
OrHas: PROC [map: Map, elt: VersionTuple] RETURNS [BOOL] ~ {
b: Binary ~ NARROW[map.data];
RETURN [b.a.Has[elt] OR b.b.Has[elt]]};
AndScan: PROC [map: Map, Consume: TupleConsumer, inOrder: BOOL, pfml: PatternFactoredMapList] RETURNS [MaybeTuple] ~ {
b: Binary ~ NARROW[map.data];
RETURN b.a.FactoredScan[Consume, inOrder, PfmlAddMap[pfml, b.b]]};
OrScan: PROC [map: Map, Consume: TupleConsumer, inOrder: BOOL, pfml: PatternFactoredMapList] RETURNS [MaybeTuple] ~ {
b: Binary ~ NARROW[map.data];
IF inOrder AND NOT b.ordered THEN RETURN SortScan[map, map.class.Scan, Consume, pfml];
{mt1: MaybeTuple ~ b.a.FactoredScan[Consume, inOrder, IF b.test=other THEN PfmlAddMap[pfml, b.b.Negate[]] ELSE pfml];
IF mt1.found THEN RETURN [mt1];
RETURN b.b.FactoredScan[Consume, inOrder, IF b.test=map THEN PfmlAddMap[pfml, b.a.Negate[]] ELSE pfml]}};
AndCreateGenerator: PROC [map: Map, inOrder: BOOL, pfml: PatternFactoredMapList] RETURNS [Generator] ~ {
b: Binary ~ NARROW[map.data];
RETURN b.a.FactoredCreateGenerator[inOrder, PfmlAddMap[pfml, b.b]]};
OrCreateGenerator: PROC [map: Map, inOrder: BOOL, pfml: PatternFactoredMapList] RETURNS [Generator] ~ {
b: Binary ~ NARROW[map.data];
g1: Generator ~ b.a.FactoredCreateGenerator[inOrder, IF b.test=other THEN PfmlAddMap[pfml, b.b.Negate[]] ELSE pfml];
g2: Generator ~ b.b.FactoredCreateGenerator[inOrder, IF b.test=map THEN PfmlAddMap[pfml, b.a.Negate[]] ELSE pfml];
RETURN g1.GeneratorUnion[g2, inOrder]};
AndNegate: PROC [map: Map] RETURNS [Map] ~ {
b: Binary ~ NARROW[map.data];
notA: Map ~ b.a.Negate[];
notB: Map ~ b.b.Negate[];
RETURN Union[notA, notB, other]};
OrNegate: PROC [map: Map] RETURNS [Map] ~ {
b: Binary ~ NARROW[map.data];
notA: Map ~ b.a.Negate[];
notB: Map ~ b.b.Negate[];
IF b.test=map THEN RETURN Intersect[notB, notA];
RETURN Intersect[notA, notB]};
AndIsIntersection: PROC [map: Map] RETURNS [Maybe2Maps] ~ {
b: Binary ~ NARROW[map.data];
RETURN [[TRUE, b.a, b.b]]};
OrIsUnion: PROC [map: Map] RETURNS [Maybe2Maps] ~ {
b: Binary ~ NARROW[map.data];
RETURN [[TRUE, b.a, b.b]]};
CreateSingleton: PUBLIC PROC [elt: VersionTuple] RETURNS [Map] ~ {
RETURN [[singletonClass, NEW [VersionTuple ← elt]]]};
singletonClass: MapClass ~ FillinDefaults[TRUE, constant, [
Has: SingletonHas,
Scan: SingletonScan,
Size: SizeIsOne,
PatternFactorMap: SingletonPatternFactorMap,
data: NIL]];
SingletonHas: PROC [map: Map, elt: VersionTuple] RETURNS [BOOL] ~ {
re: REF VersionTuple ~ NARROW[map.data];
RETURN TEqual[elt, re^]};
SingletonScan: PROC [map: Map, Consume: TupleConsumer, inOrder: BOOL, pfml: PatternFactoredMapList] RETURNS [MaybeTuple] ~ {
re: REF VersionTuple ~ NARROW[map.data];
IF pfml#[] AND NOT PfmlHas[pfml, re^] THEN RETURN [noMaybe];
IF Consume[re^] THEN RETURN [[TRUE, re^]] ELSE RETURN [noMaybe]};
SizeIsOne: PROC [map: Map, limit: INT] RETURNS [INT] ~ {RETURN [1]};
SingletonPatternFactorMap: PROC [map: Map] RETURNS [PatternFactoredMap] ~ {
re: REF VersionTuple ~ NARROW[map.data];
RETURN [[re^, aFull, aFull]]};
CreateMatcher: PUBLIC PROC [pattern: VersionTuple] RETURNS [Map] ~ {
IF PatternIsConstant[pattern] THEN RETURN CreateSingleton[pattern];
RETURN [[matcherClass, NEW [VersionTuple ← pattern]]]};
matcherClass: MapClass ~ FillinDefaults[FALSE, constant, [
Has: MatcherHas,
Size: FullSize,
PatternFactorMap: MatcherPatternFactorMap,
data: NIL]];
MatcherHas: PROC [map: Map, elt: VersionTuple] RETURNS [BOOL] ~ {
rp: REF VersionTuple ~ NARROW[map.data];
RETURN TMatches[elt, rp^]};
MatcherPatternFactorMap: PROC [map: Map] RETURNS [PatternFactoredMap] ~ {
rp: REF VersionTuple ~ NARROW[map.data];
RETURN [[rp^, aFull, aFull]]};
CreateSetMatcher: PUBLIC PROC [prefix: VersionTuple, suffixes: LOR] RETURNS [Map] ~ {
lc: MPfsN.Component ~ prefix.name.ShortName[];
lcr: ROPE ~ lc.ComponentRope[--must, and does, exclude version part--];
sm: SetMatcher ~ NEW [SetMatcherPrivate ← [
prefix,
suffixes,
prefix.name.ReplaceShortName[MPfsN.ConstructComponent[name: [lcr.Concat["*"]], version: lc.version]],
lcr.Length[]
]];
IF suffixes=NIL THEN RETURN [anEmpty];
RETURN [[setMatcherClass, sm]]};
SetMatcher: TYPE ~ REF SetMatcherPrivate;
SetMatcherPrivate: TYPE ~ RECORD [
prefix: VersionTuple,
suffixes: LOR,
prefixPattern: Name,
variableStart: NAT
];
setMatcherClass: MapClass ~ FillinDefaults[FALSE, constant, [
Has: SetMatcherHas,
Size: FullSize,
PatternFactorMap: SetMatcherPatternFactorMap,
data: NIL]];
SetMatcherHas: PROC [map: Map, elt: VersionTuple] RETURNS [BOOL] ~ {
sm: SetMatcher ~ NARROW[map.data];
IF NOT TMatches[elt, [sm.prefixPattern, sm.prefix.created, sm.prefix.stamp]] THEN RETURN [FALSE];
{lc: MPfsN.Component ~ elt.name.ShortName[];
suff: RopeParts.RopePart ~ MPfsN.ComponentName[lc].Substr[start: sm.variableStart];
FOR ss: LOR ← sm.suffixes, ss.rest WHILE ss#NIL DO
IF RopeParts.Match[RopeParts.Make[ss.first], suff, FALSE] THEN RETURN [TRUE];
ENDLOOP;
RETURN [FALSE]}};
SetMatcherPatternFactorMap: PROC [map: Map] RETURNS [PatternFactoredMap] ~ {
sm: SetMatcher ~ NARROW[map.data];
RETURN [[[sm.prefixPattern, sm.prefix.created, sm.prefix.stamp], map, aFull]]};
END.