DIRECTORY AlpsBool, AlpsHeur, Commander, Convert, GeneralRefTab, Process, Rope; AlpsHeurImpl: CEDAR PROGRAM IMPORTS AlpsBool, Convert, GeneralRefTab, Process, Rope EXPORTS AlpsHeur = BEGIN OPEN AlpsHeur; ROPE: PUBLIC TYPE = Rope.ROPE; VarNb: TYPE = AlpsBool.VarNb; CompClass: TYPE = AlpsBool.CompClass; OutputType: TYPE = AlpsBool.OutputType; ImproveAreaAndDelay: PUBLIC TableComparisonProc = { oldArea, newArea, oldSize, newSize, oldDeep, newDeep: INT; [area: oldArea, sigmaSize: oldSize, maxDeep: oldDeep] _ AlpsBool.TableStatistics[oldTable]; [area: newArea, sigmaSize: newSize, maxDeep: newDeep] _ AlpsBool.TableStatistics[newTable]; IF oldArea>newArea THEN RETURN [TRUE]; IF oldAreanewSize THEN RETURN [TRUE]; IF oldSizenewDeep THEN RETURN [TRUE]; RETURN [FALSE]; }; ImproveSizeAndDelay: PUBLIC TableComparisonProc = { oldSize, newSize, oldDeep, newDeep: INT; [sigmaSize: oldSize, maxDeep: oldDeep] _ AlpsBool.TableStatistics[oldTable]; [sigmaSize: newSize, maxDeep: newDeep] _ AlpsBool.TableStatistics[newTable]; newIsBetter _ TRUE; IF oldSizebestNbUsed THEN {bestNbUsed _ nbUsed^; bestCaseXY _ caseXY; exprs _ LIST[expr]; RETURN}; IF nbUsed^bestCaseXY THEN {bestCaseXY _ caseXY; exprs _ LIST[expr]; RETURN}; exprs _ CONS[expr, exprs]; }; used: GeneralRefTab.Ref _ GeneralRefTab.Create[Hash, Equal, table.size]; bestNbUsed: INT _ FIRST[INT]; bestCaseXY: INT _ FIRST[INT]; FOR outs: LIST OF AlpsBool.OutputRef _ table.outputs, outs.rest WHILE outs#NIL DO AlpsBool.Enumerate[outs.first.expr, RegisterExprRec]; ENDLOOP; [] _ GeneralRefTab.Pairs[used, FindBestPairs]; END; DefaultInterestProc: PUBLIC InterestProc = { exprIsInteresting _ AlpsBool.NbOfCaseXY[table, expr]>0; }; EnumerateRestrictions: PUBLIC PROC [table: AlpsBool.TableOfVariables, eachRestriction: EachRestrictionProc, interestProc: InterestProc _ DefaultInterestProc] = { Hash: GeneralRefTab.HashProc -- [key: GeneralRefTab.Key] RETURNS [hashIndex: CARDINAL] -- = { expr: AlpsBool.Expression _ NARROW[key]; RETURN[CARDINAL[expr.varNb]]; }; Equal: GeneralRefTab.EqualProc -- [val1: GeneralRefTab.Val, val2: GeneralRefTab.Val] RETURNS [BOOL] -- = { expr1: AlpsBool.Expression _ NARROW[key1]; expr2: AlpsBool.Expression _ NARROW[key2]; RETURN [AlpsBool.Equal[table, expr1, expr2] OR AlpsBool.Equal[table, expr1, expr2, FALSE]] }; Add: PROC [ref: GeneralRefTab.Ref, expr: AlpsBool.Expression, nb: INT _ 1] = { val: GeneralRefTab.Val _ GeneralRefTab.Fetch[ref, expr].val; refInt: REF INT _ IF val=NIL THEN NEW[INT _ 0] ELSE NARROW[val]; IF ~interestProc[table, expr] THEN RETURN; refInt^ _ refInt^ + nb; [] _ GeneralRefTab.Store[ref, expr, refInt]; }; restrictions: GeneralRefTab.Ref _ GeneralRefTab.Create[Hash, Equal, table.size]; FOR outputs: LIST OF AlpsBool.OutputRef _ table.outputs, outputs.rest WHILE outputs#NIL DO Add[restrictions, outputs.first.expr] ENDLOOP; WHILE GeneralRefTab.GetSize[restrictions]#0 DO newRestrictions: GeneralRefTab.Ref _ GeneralRefTab.Create[Hash, Equal, table.size]; AddExprToNewRestrictions: GeneralRefTab.EachPairAction = { expr: AlpsBool.Expression _ NARROW[key]; refInt: REF INT _ NARROW[val]; exprs: GeneralRefTab.Ref _ GeneralRefTab.Create[Hash, Equal, table.size]; AddExprLow: GeneralRefTab.EachPairAction = { Add[newRestrictions, NARROW[key], refInt^]; }; Process.Yield[]; Process.SetPriority[Process.priorityBackground]; FOR varNb: VarNb IN [1..table.size) DO [] _ GeneralRefTab.Store[exprs, AlpsBool.ExprWhenVarIs[table, expr, varNb, TRUE], NIL]; [] _ GeneralRefTab.Store[exprs, AlpsBool.ExprWhenVarIs[table, expr, varNb, FALSE], NIL]; ENDLOOP; [] _ GeneralRefTab.Pairs[exprs, AddExprLow]; }; ApplyToEachInteresting: GeneralRefTab.EachPairAction = { expr: AlpsBool.Expression _ NARROW[key]; refInt: REF INT _ NARROW[val]; IF refInt^>1 THEN quit _ eachRestriction[table, expr, refInt^]; }; [] _ GeneralRefTab.Pairs[restrictions, AddExprToNewRestrictions]; IF GeneralRefTab.Pairs[newRestrictions, ApplyToEachInteresting] THEN EXIT; restrictions _ newRestrictions; ENDLOOP; }; RenumProc: TYPE = AlpsBool.RenumProc; FactorizeOutput: PUBLIC PROC [table: AlpsBool.TableOfVariables, auxOutput: AlpsBool.OutputRef] RETURNS [newTable: AlpsBool.TableOfVariables] = BEGIN Renum: RenumProc = {RETURN [IF oldVarNb=LAST[VarNb]-1 THEN {Output["No more variable\n"]; RETURN}; newTable _ FactorizeOutput[table, auxOutput]; FOR j: VarNb DECREASING IN [1..table.size) DO newNewTable: AlpsBool.TableOfVariables _ AlpsBool.Permute2Vars[newTable, 1, j]; Output["."]; IF better[newTable, newNewTable] THEN newTable _ newNewTable; ENDLOOP; IF ~better[table, newTable] THEN LOOP; Output["\nFactorized: "]; [] _ AlpsBool.PrintExpression[table, auxOutput, printLevel]; Output["\n"]; table _ newTable; ok _ TRUE; ENDLOOP; table _ newTable; END; FastPermute: PUBLIC PROC [table: AlpsBool.TableOfVariables, better: TableComparisonProc] RETURNS [newTable: AlpsBool.TableOfVariables, ok: BOOL _ FALSE] = { FOR i: VarNb DECREASING IN (1 .. table.size) DO Output["."]; newTable _ AlpsBool.Permute2Vars[table, i, i-1]; IF better[table, newTable] THEN { Output["Permuting variable ", table[i].name, " (#", Convert.RopeFromInt[i], ") and variable ", Rope.Cat[table[i-1].name, " (#", Convert.RopeFromInt[i-1], ")\n"]]; ok _ TRUE; table _ newTable; }; ENDLOOP; }; AllPermute: PUBLIC PROC [table: AlpsBool.TableOfVariables, better: TableComparisonProc, permutLimit: INT _ 99] RETURNS [newTable: AlpsBool.TableOfVariables] = { minNbCaseXY: INT _ LAST[INT]; SigmaNbCaseXY: PROC [table: AlpsBool.TableOfVariables] RETURNS [nb: INT _ 0] = { FOR outs: LIST OF AlpsBool.OutputRef _ table.outputs, outs.rest WHILE outs#NIL DO nb _ nb + AlpsBool.NbOfCaseXY[table, outs.first.expr]; ENDLOOP; }; AlreadyNbCaseXY: PROC [table: AlpsBool.TableOfVariables, varNb: VarNb] RETURNS [nb: INT _ 0] = { AddCaseXY: AlpsBool.EachNodeProc = {quit _ expr.varNb<=varNb; IF expr.varNb>=varNb AND expr.case=caseXY THEN nb _ nb+1}; FOR outs: LIST OF AlpsBool.OutputRef _ table.outputs, outs.rest WHILE outs#NIL DO AlpsBool.Enumerate[outs.first.expr, AddCaseXY]; ENDLOOP; }; NbCaseXYOnVar: PROC [table: AlpsBool.TableOfVariables, varNb: VarNb] RETURNS [nb: INT _ 0] = { AddCaseXY: AlpsBool.EachNodeProc = {quit _ expr.varNb<=varNb; IF expr.varNb=varNb AND expr.case=caseXY THEN nb _ nb+1}; FOR outs: LIST OF AlpsBool.OutputRef _ table.outputs, outs.rest WHILE outs#NIL DO AlpsBool.Enumerate[outs.first.expr, AddCaseXY]; ENDLOOP; }; AllPermuteRec: PROC [table: AlpsBool.TableOfVariables, varNb: VarNb] RETURNS [newTable: AlpsBool.TableOfVariables] = { IF varNb=0 THEN RETURN[table]; IF AlreadyNbCaseXY[table, varNb]>minNbCaseXY THEN RETURN[table]; -- no good IF NbCaseXYOnVar[table, varNb]=0 THEN RETURN[AllPermuteRec[table, varNb-1]]; FOR other: VarNb DECREASING IN [1..varNb) DO Output["."]; newTable _ AlpsBool.Permute2Vars[table, varNb, other]; IF NbCaseXYOnVar[newTable, varNb]=0 THEN { Output["!"]; RETURN[AllPermuteRec[newTable, varNb-1]]; }; IF better[table, newTable] THEN table _ newTable; ENDLOOP; table _ AllPermuteRec[table, varNb-1]; minNbCaseXY _ MIN [minNbCaseXY, SigmaNbCaseXY[table]]; IF permutLimit=0 THEN {Output["\nAborted\n"]; RETURN[table]}; permutLimit _ permutLimit - 1; FOR other: VarNb DECREASING IN [1..varNb) DO Output["'"]; newTable _ AlpsBool.Permute2Vars[table, varNb, other]; newTable _ AllPermuteRec[newTable, varNb-1]; IF better[table, newTable] THEN { table _ newTable; }; ENDLOOP; newTable _ table; }; newTable _ AllPermuteRec[table, table.size-1]; }; BestPermute: PUBLIC PROC [table: AlpsBool.TableOfVariables, better: TableComparisonProc] RETURNS [newTable: AlpsBool.TableOfVariables, ok: BOOL _ FALSE] = { FOR i: VarNb DECREASING IN [1 .. table.size) DO bestTable: AlpsBool.TableOfVariables _ table; bestJ: INT _ i; FOR j: VarNb DECREASING IN [1..i) DO Output["."]; newTable _ AlpsBool.Permute2Vars[table, i, j]; IF better[bestTable, newTable] THEN { bestTable _ newTable; bestJ _ j; }; ENDLOOP; IF bestJ#i THEN { Output["Permuting variable ", table[i].name, " (#", Convert.RopeFromInt[i], ") and variable ", Rope.Cat[table[bestJ].name, " (#", Convert.RopeFromInt[bestJ], ")\n"]]; ok _ TRUE; table _ bestTable; }; ENDLOOP; newTable _ table; }; BestPermuteInfinitely: PUBLIC PROC [table: AlpsBool.TableOfVariables, better: TableComparisonProc] RETURNS [newTable: AlpsBool.TableOfVariables] = { ok: BOOL _ TRUE; Output["Starting permutations\n"]; WHILE ok DO newTable: AlpsBool.TableOfVariables; Output["Permuting ...\n"]; [newTable, ok] _ BestPermute[table, better]; IF ok THEN table _ newTable; ENDLOOP; Output["Permutations finished\n"]; newTable _ table; }; NbOfUseOfVarInTable: PUBLIC PROC [table: AlpsBool.TableOfVariables, varNb: VarNb] RETURNS [sigma: INT _ 0] = BEGIN FOR outs: LIST OF AlpsBool.OutputRef _ table.outputs, outs.rest WHILE outs#NIL DO sigma _ sigma + AlpsBool.NbUsedVar[outs.first.expr, varNb]; ENDLOOP; END; RemoveAuxVar: PUBLIC PROC [table: AlpsBool.TableOfVariables, better: TableComparisonProc, printLevel: INT _ 2] RETURNS [newTable: AlpsBool.TableOfVariables, ok: BOOL] = BEGIN renum: REF RenumSeq _ NEW[RenumSeq[table.size]]; RenumSeq: TYPE = RECORD [contents: SEQUENCE size: VarNb OF VarNb]; Renum: RenumProc = {RETURN[renum[oldVarNb]]}; auxOutputs: LIST OF AlpsBool.OutputRef _ NIL; min: INT _ LAST [INT]; minCaseXY: INT _ LAST [INT]; nb: INT _0; IsGoingToBeDeleted: PROC [aux: AlpsBool.VarNb] RETURNS [BOOL _ FALSE] = { FOR list: LIST OF AlpsBool.OutputRef _ auxOutputs, list.rest WHILE list#NIL DO IF list.first.fedBackInput=aux THEN RETURN [TRUE]; ENDLOOP; }; FOR outs: LIST OF AlpsBool.OutputRef _ table.outputs, outs.rest WHILE outs#NIL DO IF outs.first.type=aux THEN BEGIN use: INT _ NbOfUseOfVarInTable[table, outs.first.fedBackInput]; caseXY: INT _ AlpsBool.NbOfCaseXY[table, outs.first.expr]; IF caseXY=minCaseXY AND use=min THEN auxOutputs _ CONS [outs.first, auxOutputs]; IF caseXYcaseXY AND thisNb>=nb) OR (thisCaseXY>=caseXY AND thisNb>nb) THEN quit _ TRUE; }; MakeNewVizir: GeneralRefTab.EachPairAction = { thisExpr: AlpsBool.Expression _ NARROW[key]; refInt: REF INT _ NARROW[val]; thisNb: INT _ refInt^; thisCaseXY: INT _ AlpsBool.NbOfCaseXY[table, thisExpr]; IF ~((thisCaseXY -- [key: GeneralRefTab.Key] RETURNS [hashIndex: CARDINAL] -- šžœÐck=œ˜^Jšœœ˜(Jšœœ˜J˜—–I -- [val1: GeneralRefTab.Val, val2: GeneralRefTab.Val] RETURNS [BOOL] -- šžœ¡Hœ˜kJšœœ˜*Jšœœ˜*Jšœ&œ%œ˜ZJ˜—šŸœ œ ¡?œ˜jJšœ=˜=Jšœœœœœœœœœœ˜@J˜Jšœ-˜-Jšœ˜—–P -- [key: GeneralRefTab.Key, val: GeneralRefTab.Val] RETURNS [quit: BOOLEAN] -- šž œ¡Oœ˜Jšœœœœ˜Jšœœ˜(Jšœœ$˜/Jšœœ˜ Jšœ œœ˜Jšœœ5œœ˜cJšœœœœ˜7Jšœœœœ˜LJšœ™Jšœœ˜J˜—JšœH˜HJš œ œœœœœœ˜;Jšœ™š œœœ/œœ˜QJšœ5˜5Jšœ˜—Jšœ™Jšœ.˜.Jšœ˜—J˜šžœœ˜,Jšœ7˜7J˜J˜—šŸœœœ˜¡–> -- [key: GeneralRefTab.Key] RETURNS [hashIndex: CARDINAL] -- šžœ¡=œ˜^Jšœœ˜(Jšœœ˜J˜—–I -- [val1: GeneralRefTab.Val, val2: GeneralRefTab.Val] RETURNS [BOOL] -- šžœ¡Hœ˜kJšœœ˜*Jšœœ˜*Jšœ&œ%œ˜ZJ˜—šŸœœ9œ ˜NJšœ<˜œœ˜JJšœ˜Jšœ˜—J˜—J˜J˜Jšœ œ˜%J˜š   žœœœCœ(˜ŽJš˜šžœ˜Jš œœœ!œ œ˜L—Jšœ7˜7Jšœ7˜7Jšœ(˜(šœ œ˜$Jšœ(˜(Jšœ˜—š œ œœ2œ œ˜Zšœœ˜7Jšœ4˜4JšœI˜IJšœ˜—Jšœ˜—š œ œœ2œ œ˜ZJšœœo˜ŽJšœ˜—Jšœ˜—J˜š Ÿ œœœMœœ+œ˜©Jš˜Jšœœ˜ š œœœ3œœœ˜Xšœ œ˜:Jšœb˜bJšœ˜—Jšœ œ œ œ˜IJšœ-˜-Jšœ™šœ œœ˜-JšœO˜OJšœ ˜ Jšœœ˜=Jšœ˜—Jšœ2™2Jšœœœ˜&Jšœ˜Jšœ<˜ -- [key: GeneralRefTab.Key] RETURNS [hashIndex: CARDINAL] -- šžœ¡=œ™^Jšœœ™(Jšœœ™J™—–I -- [val1: GeneralRefTab.Val, val2: GeneralRefTab.Val] RETURNS [BOOL] -- šžœ¡Hœ™kJšœœ™*Jšœœ™*Jšœ&œ%œ™ZJ™—šž œ™#Jšœœ$™/JšœO™Ošžœ"™*Jšœ œ™,Jšœœœœ™Jšœœ ™Jšœ œ(™7Jš œœ œœ œœ™]J™—šž œ"™.Jšœ œ™,Jšœœœœ™Jšœœ ™Jšœ œ(™7Jš œœ œœ œ1œ ™•J™—J™ Jšœ)œœ™7J™ Jšœ,œœ™;Jšœ1™1Jšœ™J™—šž œ"™/Jšœœ™(Jš œœœœœ™ Jšœœ$™/šœ™Jšœ3œ™FJšœ-™-Jšœ3™3—J™—Jšœ)™)Jšœ2™2Jšœ œ™Jšœ™—J˜š Ÿ œœœAœ+œœ˜œšœ œœ˜/Jšœ ˜ Jšœ0˜0šœœ˜!Jšœ£˜£Jšœœ˜Jšœ˜—Jšœ˜—J˜—J˜š Ÿ œœœNœœ*˜ Jšœ œœœ˜šŸ œœ$œœ ˜Pš œœœ/œœ˜QJšœ6˜6Jšœ˜—J˜—šŸœœ2œœ ˜`Jšž œ5œœœ ˜xš œœœ/œœ˜QJšœ/˜/Jšœ˜—J˜—šŸ œœ2œœ ˜^Jšž œ5œœœ ˜wš œœœ/œœ˜QJšœ/˜/Jšœ˜—J˜—šŸ œœ2œ*˜vJšœ œœ˜Jšœ+œœ Ïc ˜KJšœœœ ˜LJšœ"™"šœ œœ ˜,Jšœ ˜ Jšœ6˜6šœ"œ˜*Jšœ œ#˜6J˜—Jšœœ˜1Jšœ˜—Jšœ™Jšœ&˜&Jšœœ%˜6Jšœœœ ˜=Jšœ˜šœ œœ ˜,Jšœ ˜ Jšœ6˜6Jšœ,˜,šœœ˜!Jšœ®™®Jšœ˜J˜—Jšœ˜—Jšœ˜J˜—Jšœ.˜.J˜—J˜š Ÿ œœœAœ+œœ˜œšœ œœ˜/Jšœ-˜-Jšœœ˜šœ œœ˜$Jšœ ˜ Jšœ.˜.šœœ˜%Jšœ ˜ J˜—Jšœ˜—šœ œ˜Jšœ ™ Jšœ¦˜¦Jšœœ˜J˜—Jšœ˜—Jšœ˜J˜—J˜šŸœœœAœ*˜”Jšœœœ˜J˜"šœœ˜ Jšœ$˜$J˜Jšœ,˜,Jšœœ˜Jšœ˜—J˜"Jšœ˜J˜—J™š Ÿœœœ2œ œ˜lJš˜š œœœ/œœ˜QJšœ;˜;Jšœ˜—Jšœ˜—J˜š Ÿ œœœMœœ+œ˜¨Jš˜J–[]šœœ œ˜0Jš žœœœ œ œ˜BJšžœœ˜-Jšœ œœœ˜.Jšœœœœ˜Jšœ œœœ˜Jšœœ˜ š Ÿœœœœœ˜Iš œœœ,œœ˜NJšœœœœ˜2Jšœ˜—J˜—Jšœ-™-š œœœ/œœ˜Qšœœ˜Jš˜Jšœœ7˜?Jšœœ/˜:Jšœœ œœ˜Pšœœœ œ˜Jšœ˜—Jšœ˜—Jšœ˜—Jš œ œœœ œ˜-J˜šœœ œ˜,Jšœœœ˜LJšœ˜—š œœœœ,œœ˜VJšœ ˜ Jšœ˜—Jšœ8˜8šœ œ˜$Jšœ œ)˜;Jšœ˜—š œœœ/œœ˜Qšœ.œ˜6Jšœ,˜,š œœœ,œœ˜NJšœR˜RJšœ˜—Jšœ3˜3Jšœœ˜¡J˜—Jšœ˜—J˜Jšœœœ œ˜7š œœœ,œœ˜NJšœ(˜(Jšœ=˜=Jšœ7˜7Jšœ˜—Jšœ œ˜Jšœ˜—J˜š œœœ$œ*˜iJ–[]š žœœœ œœ˜LJšœ5˜5šœ œœ˜%Jšœ(˜(Jšœ˜—š œœœ/œœ˜QJšœ(˜(Jšœœ¢˜ÂJšœ˜—Jšœ˜——J˜Jšœ˜—J˜—…—Dlg‹