LichenStructureComparison:
CEDAR
PROGRAM
IMPORTS AbSets, BiRels, LichenArrayPrivate, LichenDataStructure, SetBasics
EXPORTS LichenDataStructure
=
StructurallyEquivalent:
PUBLIC
PROC [cta, ctb: CellType]
RETURNS [equiv:
BOOL, assoc: OneToOne ← nilBiRel] ~ {
aa: Array ~ cta.asArray;
ab: Array ~ ctb.asArray;
portsA: Set ~ cta.CTParts[p];
portsB: Set ~ ctb.CTParts[p];
IF cta.d#ctb.d THEN ERROR;
IF aa=NIL OR ab=NIL THEN ERROR nyet;
IF aa.size2 # ab.size2 OR aa.basePeriod # ab.basePeriod THEN RETURN [FALSE];
IF portsA.Size # portsB.Size THEN RETURN [FALSE];
{d: Design ~ cta.d;
sra: StatRep ~ aa.statrep;
srb: StatRep ~ ab.statrep;
CheckStatEdge:
PROC [val: Sets.Value]
RETURNS [
BOOL] ~ {
sea: StatEdge ~ NARROW[val.VA];
sepa: StatEdgeSpec ~ sea.SeSp[sra];
IF FindStatEdge[srb, sepa, FALSE].fse=NIL THEN RETURN [TRUE];
RETURN [FALSE]};
DoEasyPort:
PROC [pair: BiRels.Pair]
RETURNS [
BOOL] ~ {
apa: Port ~ NARROW[pair[left].VA];
pai: PortAtIndex ~ VPai[pair[right]];
apbs: Set ~ srb.apToPAI.Mapping[pair[right], rightToLeft];
SELECT apbs.Size[
IS.two]
FROM
IS.zero => RETURN [TRUE];
IS.one => {assoc.AddNewAA[apa, apbs.AnElt.MA]; RETURN [FALSE]};
ENDCASE => ERROR--we're assuming merged ports--};
DoHardPort:
PROC [pav: Sets.Value]
RETURNS [
BOOL] ~ {
IF assoc.Apply[pav].found THEN RETURN [FALSE];
{pa: Port ~ NARROW[pav.VA];
kidsa: Seq ~ d.SubSeq[pa];
IF kidsa.SetOn[right].Scan[DoHardPort].found THEN RETURN [TRUE];
{kidsb: Seq ~ kidsa.Compose[assoc, [TRUE, FALSE]];
si: SubsIndex ~ d.SubseqIndex[kidsb];
IF NOT si.full THEN RETURN [TRUE];
assoc.AddNewAA[pa, si.parent];
RETURN [FALSE]}}};
IF sra.edges.Size # srb.edges.Size THEN RETURN [FALSE];
IF sra.apToPAI.Size # srb.apToPAI.Size THEN RETURN [FALSE];
IF sra.edges.Scan[CheckStatEdge].found THEN RETURN [FALSE];
assoc ← BiRels.CreateHashOTO[ALL[d.eSpace]];
IF sra.apToPAI.Scan[DoEasyPort].found THEN RETURN [FALSE];
IF portsA.Scan[DoHardPort].found THEN RETURN [FALSE];
equiv ← TRUE}};