DIRECTORY Core, CoreBoole, CoreBooleExtras, CoreOps, CoreProperties, FS, IO, Process, Rope, RopeList, TerminalIO; CoreBooleExtrasImpl: CEDAR PROGRAM IMPORTS CoreBoole, CoreOps, CoreProperties, FS, IO, Rope, RopeList, TerminalIO EXPORTS CoreBooleExtras = BEGIN OPEN CoreBooleExtras; false: Expression = CoreBoole.false; true: Expression = CoreBoole.true; Size: PUBLIC PROC [expr: Expression] RETURNS [size: INT _ 0] = { var: ROPE _ CoreBoole.FindVar[expr]; whenTrue, whenFalse: Expression; IF var=NIL THEN RETURN; [whenTrue, whenFalse] _ CoreBoole.Eval[var, expr]; IF CoreBoole.Equal[whenTrue, true] OR CoreBoole.Equal[whenTrue, false] THEN RETURN[Size[whenFalse]]; IF CoreBoole.Equal[whenFalse, true] OR CoreBoole.Equal[whenFalse, false] THEN RETURN[Size[whenTrue]]; size _ 1 + Size[whenTrue] + Size[whenFalse]; }; Reorder: PUBLIC PROC [expr: Expression, public: Wire] RETURNS [newExpr: Expression] = { vars: LIST OF ROPE _ NIL; AddToVars: CoreOps.EachWireProc = { IF wire.size=0 THEN vars _ CONS [CoreOps.GetShortWireName[wire], vars]; }; [] _ CoreOps.VisitWire[public, AddToVars]; vars _ RopeList.Reverse[vars]; RETURN [ReorderVars[expr, vars]]; }; ReorderVars: PUBLIC PROC [expr: Expression, vars: LIST OF ROPE] RETURNS [newExpr: Expression] = { var: ROPE; whenTrue, whenFalse: Expression; IF expr=true OR expr=false THEN RETURN [expr]; var _ vars.first; [whenTrue, whenFalse] _ CoreBoole.Eval[var, expr]; newExpr _ CoreBoole.If[CoreBoole.Var[var], ReorderVars[whenTrue, vars.rest], ReorderVars[whenFalse, vars.rest]]; }; coreBoolePermuteProp: PUBLIC ATOM _ CoreProperties.RegisterProperty[$CoreBoolePermuteProp]; Permute: PUBLIC PROC [expr: Expression, public: Wire] RETURNS [bestPermutedExpr: Expression, bestPermutedWire: Wire] = { }; ReadPLAFile: PUBLIC PROC [fileName: ROPE, inputs, outputs: LIST OF ROPE _ NIL] RETURNS [exprs: ExprsSeq] = BEGIN terms: ExprsSeq; SkipNext: PUBLIC PROC [rope: ROPE] RETURNS [ROPE] = {RETURN [IF rope.IsEmpty THEN rope ELSE Rope.Substr[rope, 1]]}; SkipWhite: PUBLIC PROC [rope: ROPE] RETURNS [ROPE] = {RETURN [IF rope.IsEmpty OR rope.Fetch[0]#' THEN rope ELSE SkipWhite[SkipNext[rope]]]}; Nth: PROC [list: LIST OF ROPE, n: INT] RETURNS [x: ROPE] = { WHILE n>0 DO list _ list.rest; n _ n-1 ENDLOOP; x _ list.first; }; Skip: PROC [rope: ROPE] RETURNS [ROPE] = {RETURN[SkipWhite[SkipNext[rope]]]}; inStm: IO.STREAM _ FS.StreamOpen[fileName: fileName]; nbins, nbterms, nbouts: NAT _ 0; DO -- for each line ENABLE IO.EndOfStream => EXIT; rope: ROPE _ SkipWhite[IO.GetLineRope[inStm]]; IF rope.IsEmpty OR (SELECT rope.Fetch[0] FROM '0, '1, '., '-, 'x, 'X => FALSE, ENDCASE => TRUE) THEN LOOP; WHILE ~rope.IsEmpty AND rope.Fetch[0]#'| DO IF nbterms=0 THEN nbins _ nbins+1; rope _ Skip[rope]; ENDLOOP; rope _ Skip[rope]; WHILE ~rope.IsEmpty DO IF nbterms=0 THEN nbouts _ nbouts+1; rope _ Skip[rope]; ENDLOOP; TerminalIO.WriteF["."]; nbterms _ nbterms+1; ENDLOOP; IF inputs=NIL AND outputs=NIL THEN { TerminalIO.WriteF["First pass on %g done: %g inputs; %g terms; %g outputs.\n", IO.rope[fileName], IO.int[nbins], IO.int[nbterms], IO.int[nbouts]]; FOR i: INT DECREASING IN [0..nbins) DO inputs _ CONS [Rope.Cat["Input", IO.PutR[IO.int[i]]], inputs]; ENDLOOP; FOR i: INT DECREASING IN [0..nbouts) DO outputs _ CONS [Rope.Cat["Output", IO.PutR[IO.int[i]]], outputs]; ENDLOOP; } ELSE { IF nbins#RopeList.Length[inputs] THEN {TerminalIO.WriteF["*** Number of inputs of the TruthTable (%g) does NOT agree with the inputs given.\n", IO.int[nbins]]; ERROR}; IF nbouts#RopeList.Length[outputs] THEN {TerminalIO.WriteF["*** Number of outputs of the TruthTable (%g) does NOT agree with the outputs given.\n", IO.int[nbouts]]; ERROR}; }; exprs _ NEW[ExprsSeqRec[nbouts]]; FOR i: NAT IN [0 .. nbouts) DO exprs[i] _ false ENDLOOP; terms _ NEW[ExprsSeqRec[nbterms]]; inStm _ FS.StreamOpen[fileName: fileName]; TerminalIO.WriteF["\n"]; FOR term: NAT IN [0 .. nbterms) DO -- for each line termName: ROPE _ Rope.Cat["Term", IO.PutR[IO.int[term]]]; operands: LIST OF Expression _ NIL; -- operands making the AND plane rope: ROPE _ ""; WHILE rope.IsEmpty OR (SELECT rope.Fetch[0] FROM '0, '1, '., '-, 'x, 'X => FALSE, ENDCASE => TRUE) DO rope _ SkipWhite[IO.GetLineRope[inStm]] ENDLOOP; FOR input: NAT IN [0..nbins) DO IF rope.Fetch[0]='1 THEN operands _ CONS [CoreBoole.Var[Nth[inputs, nbins-input-1]], operands]; IF rope.Fetch[0]='0 THEN operands _ CONS [CoreBoole.Not[CoreBoole.Var[Nth[inputs, nbins-input-1]]], operands]; rope _ Skip[rope]; ENDLOOP; IF rope.Fetch[0]#'| THEN ERROR; rope _ Skip[rope]; terms[term] _ CoreBoole.AndList[operands]; FOR outs: NAT IN [0 .. nbouts) DO IF rope.Fetch[0]='1 THEN exprs[outs] _ CoreBoole.Or[terms[term], exprs[outs]]; ENDLOOP; TerminalIO.WriteF["."]; ENDLOOP; TerminalIO.WriteF["\n"]; END; END. †CoreBooleExtrasImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet August 13, 1985 5:47:24 pm PDT Bertrand Serlet January 20, 1986 3:17:12 pm PST SeqListWire: TYPE = REF SeqListWireRec; SeqListWireRec: TYPE = RECORD [c: SEQUENCE size: NAT OF LIST OF Wire]; CartesianProduct: PROC [seqListWire: SeqListWire, permutations: LIST OF Wire] RETURNS [newPermutations: LIST OF Wire] = { size: NAT _ seqListWire.size; wire: Wire; FOR i: NAT IN [0 .. size) DO IF seqListWire[i].rest#NIL THEN { seqListWire1: SeqListWire _ NEW [SeqListWireRec[size]]; seqListWire2: SeqListWire _ NEW [SeqListWireRec[size]]; FOR j: NAT IN [0 .. size) DO IF i#j THEN {seqListWire1[j] _ seqListWire[j]; seqListWire2[j] _ seqListWire[j]} ELSE {seqListWire1[j] _ LIST [seqListWire[j].first]; seqListWire2[j] _ seqListWire[j].rest}; ENDLOOP; newPermutations _ CartesianProduct[seqListWire1, CartesianProduct[seqListWire2, permutations]]; RETURN; }; ENDLOOP; wire _ NEW [WireRec _ [structure: record, elements: NEW [WireSequenceRec[size]]]]; FOR i: NAT IN [0 .. size) DO wire.elements[i] _ seqListWire[i].first; ENDLOOP; newPermutations _ CONS [wire, permutations]; }; PermuteSeqListWire: PROC [rank: NAT, seqListWire: SeqListWire, permutations: LIST OF SeqListWire] RETURNS [newPermutations: LIST OF SeqListWire] = { size: NAT _ seqListWire.size; newPermutations _ permutations; IF rank=0 THEN RETURN [CONS[seqListWire, newPermutations]]; FOR i: NAT IN [0 .. rank] DO newSeqListWire: SeqListWire _ NEW [SeqListWireRec[size]]; FOR j: NAT IN [0 .. size) DO newSeqListWire[j] _ seqListWire[IF j=i THEN rank ELSE IF j=rank THEN i ELSE j]; ENDLOOP; newPermutations _ PermuteSeqListWire[rank-1, newSeqListWire, newPermutations]; ENDLOOP; }; EnumeratePermutedWires: PROC [wire: Wire] RETURNS [permutations: LIST OF Wire] = { size: NAT; IF wire.structure=atom THEN RETURN [LIST[wire]]; size _ wire.elements.size; SELECT CoreProperties.GetProp[wire.properties, coreBoolePermuteProp] FROM $DoNot => RETURN [LIST[wire]]; $DoNotButDoSons => { seqListWire: SeqListWire _ NEW [SeqListWireRec[size]]; FOR i: NAT IN [0 .. size) DO seqListWire[i] _ EnumeratePermutedWires[wire.elements[i]]; ENDLOOP; permutations _ CartesianProduct[seqListWire, NIL]; }; $DoNotApartReverse => { seqListWire: SeqListWire _ NEW [SeqListWireRec[size]]; revSeqListWire: SeqListWire _ NEW [SeqListWireRec[size]]; FOR i: NAT IN [0 .. size) DO seqListWire[i] _ EnumeratePermutedWires[wire.elements[i]]; ENDLOOP; FOR i: NAT IN [0 .. size) DO revSeqListWire[i] _ seqListWire[size-i-1]; ENDLOOP; permutations _ CartesianProduct[seqListWire, NIL]; permutations _ CartesianProduct[revSeqListWire, permutations]; } ENDCASE => { seqListWire: SeqListWire _ NEW [SeqListWireRec[size]]; listSeqListWire: LIST OF SeqListWire; FOR i: NAT IN [0 .. size) DO seqListWire[i] _ EnumeratePermutedWires[wire.elements[i]]; ENDLOOP; listSeqListWire _ PermuteSeqListWire[size-1, seqListWire, NIL]; WHILE listSeqListWire#NIL DO permutations _ CartesianProduct[listSeqListWire.first, permutations]; listSeqListWire _ listSeqListWire.rest; ENDLOOP; }; }; min: INT _ LAST[INT]; permutations: LIST OF Wire _ EnumeratePermutedWires[public]; bestPermutedExpr _ expr; bestPermutedWire _ public; WHILE permutations#NIL DO expr _ Reorder[bestPermutedExpr, permutations.first]; IF Size[expr] EXIT]; Process.Yield[]; ENDLOOP; We make a first pass to count the number of inputs, terms and outputs 2nd Pass We now read for good the PLA TerminalIO.WriteF["term: %g\n", RopeFromExpression[table, expr]]; ส  – "cedar" style˜codešœ™Jšœ ฯmœ1™™>J™—šžœ ™Jšœžœ™6Jšœžœžœ ™%šžœžœžœ žœ™Jšœ:™:Jšžœ™—Jšœ:žœ™?šžœžœž™JšœE™EKšœ'™'Kšžœ™—Kšœ™——J™—Jšœžœžœžœ™Jšœžœžœ'™Jšžœ˜—š žœžœž œžœ ž˜'Jšœ žœžœžœ˜AJšžœ˜—Jšœžœ˜Jšžœžœkžœžœ˜งJšžœ!žœmžœžœ˜ฌJ˜—J˜Jšœžœ˜!Jš žœžœžœžœžœ˜8Jšœžœ˜"J˜Jšœ™Jšœžœ ˜*Jšœ˜š žœžœžœžœก˜5Jšœ žœžœžœ ˜9Jšœ žœžœžœก ˜DJšœžœ˜Jšžœžœžœžœžœžœžœžœžœžœ˜–šžœžœžœ žœ˜ Jšžœžœ žœ7˜_Jšžœžœ žœF˜nJšœ˜Jšžœ˜—Jšžœžœžœ˜Jšœ˜Jšœ*˜*JšœA™Ašžœžœžœž˜!Jšžœžœ6˜NJšžœ˜—J˜Jšžœ˜—J˜Jšžœ˜—K˜—Kšžœ˜K˜—…—ฎ+ิ