Flattening a formula to a circuit, in polynomial time #
A formula is encoded as its post-order serialization (Fml.rpn), and the circuit of a
formula (Fml.flattenAt 0) is computed from that serialization by a single left-to-right
scan with a stack of gate indices (flStep, flatten): an input or constant node emits its
gate and pushes the gate's index; a connective pops the indices of its arguments, emits the
gate and pushes the new index. The scan is a fold, so the program is a PolyTimeFun.foldl
of the step (PolyTimeFun.casesNode dispatches on the node), and Fml.toCircuitF is the
circuit of a formula on a given number of inputs as a polynomial-time function
(planning/succinct-cook-levin.md, S3).
The scan #
The state of the scan: the stack of gate indices, the gates so far (reversed), and the number of gates so far.
Equations
Instances For
One step of the scan.
Equations
- MIPRE.SAT.flStep s (MIPRE.SAT.Fml.Node.inp i) = (s.2.2 :: s.1, MIPRE.SAT.Gate.input i :: s.2.1, s.2.2 + 1)
- MIPRE.SAT.flStep s (MIPRE.SAT.Fml.Node.const b) = (s.2.2 :: s.1, MIPRE.SAT.Gate.const b :: s.2.1, s.2.2 + 1)
- MIPRE.SAT.flStep s MIPRE.SAT.Fml.Node.and = match s.1 with | g :: f :: vs => (s.2.2 :: vs, MIPRE.SAT.Gate.and f g :: s.2.1, s.2.2 + 1) | x => s
- MIPRE.SAT.flStep s MIPRE.SAT.Fml.Node.or = match s.1 with | g :: f :: vs => (s.2.2 :: vs, MIPRE.SAT.Gate.or f g :: s.2.1, s.2.2 + 1) | x => s
- MIPRE.SAT.flStep s MIPRE.SAT.Fml.Node.not = match s.1 with | f :: vs => (s.2.2 :: vs, MIPRE.SAT.Gate.not f :: s.2.1, s.2.2 + 1) | x => s
Instances For
The gates of a serialization.
Equations
- MIPRE.SAT.flatten l = (List.foldl MIPRE.SAT.flStep ([], [], 0) l).2.1.reverse
Instances For
The size of the state along the scan #
The payload of a gate: the input index of an input gate.
Equations
- (MIPRE.SAT.Gate.input i).payload = MIPRE.Cost.esize i
- x✝.payload = 0
Instances For
Along the scan, every index on the stack is bounded, and so is the state.
Dispatch on a node #
The branches of casesNodeProg, in the environments described there.
Equations
- MIPRE.SAT.FlProg.cnInp Fi = ((MIPRE.Cost.Prog.var 2).cons (MIPRE.Cost.Prog.var 1)).let_ Fi
Instances For
Equations
- MIPRE.SAT.FlProg.cnConst Fc = ((MIPRE.Cost.Prog.var 4).cons (MIPRE.Cost.Prog.var 3)).let_ Fc
Instances For
Equations
- MIPRE.SAT.FlProg.cnRest3 Fo Fn = MIPRE.Cost.Prog.elim 1 (MIPRE.Cost.Prog.callVar 8 Fo) (MIPRE.Cost.Prog.callVar 10 Fn)
Instances For
Equations
- MIPRE.SAT.FlProg.cnRest2 Fa Fo Fn = MIPRE.Cost.Prog.elim 1 (MIPRE.Cost.Prog.callVar 6 Fa) (MIPRE.SAT.FlProg.cnRest3 Fo Fn)
Instances For
Equations
- MIPRE.SAT.FlProg.cnRest1 Fc Fa Fo Fn = MIPRE.Cost.Prog.elim 1 (MIPRE.SAT.FlProg.cnConst Fc) (MIPRE.SAT.FlProg.cnRest2 Fa Fo Fn)
Instances For
Equations
- MIPRE.SAT.FlProg.cnTag Fi Fc Fa Fo Fn = MIPRE.Cost.Prog.elim 0 (MIPRE.SAT.FlProg.cnInp Fi) (MIPRE.SAT.FlProg.cnRest1 Fc Fa Fo Fn)
Instances For
Dispatch on the node of an input (a, nd): the environment after the two elims is
[tag, payload, a, nd, input], and the unary tag is inspected one nil at a time.
Equations
- MIPRE.SAT.FlProg.casesNodeProg Fi Fc Fa Fo Fn = MIPRE.Cost.Prog.elim 0 MIPRE.Cost.Prog.nil (MIPRE.Cost.Prog.elim 1 MIPRE.Cost.Prog.nil (MIPRE.SAT.FlProg.cnTag Fi Fc Fa Fo Fn))
Instances For
The function of casesNode.
Equations
- MIPRE.SAT.PolyTimeFun.casesNodeFun Fi Fc Fa Fo Fn (a, MIPRE.SAT.Fml.Node.inp i) = Fi (a, i)
- MIPRE.SAT.PolyTimeFun.casesNodeFun Fi Fc Fa Fo Fn (a, MIPRE.SAT.Fml.Node.const b) = Fc (a, b)
- MIPRE.SAT.PolyTimeFun.casesNodeFun Fi Fc Fa Fo Fn (a, MIPRE.SAT.Fml.Node.and) = Fa a
- MIPRE.SAT.PolyTimeFun.casesNodeFun Fi Fc Fa Fo Fn (a, MIPRE.SAT.Fml.Node.or) = Fo a
- MIPRE.SAT.PolyTimeFun.casesNodeFun Fi Fc Fa Fo Fn (a, MIPRE.SAT.Fml.Node.not) = Fn a
Instances For
Case analysis on a node component.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The scan as a polynomial-time function #
The gate constructors as polynomial-time functions.
Equations
Instances For
Equations
Instances For
Equations
- MIPRE.SAT.Gate.andF = MIPRE.Cost.PolyTimeFun.tagged 2 (fun (p : ℕ × ℕ) => MIPRE.SAT.Gate.and p.1 p.2) MIPRE.SAT.Gate.andF._proof_1
Instances For
Equations
- MIPRE.SAT.Gate.orF = MIPRE.Cost.PolyTimeFun.tagged 3 (fun (p : ℕ × ℕ) => MIPRE.SAT.Gate.or p.1 p.2) MIPRE.SAT.Gate.orF._proof_1
Instances For
Equations
Instances For
The step of the scan on a leaf: push the counter, emit the gate, increment.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The step of the scan on a binary connective: pop two indices, emit the gate, push. The
state is presented as ((out, cnt), vs) to casesList.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The step of the scan on a negation.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The step of the scan, as a polynomial-time function.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The Cobham condition of the scan.
The gates of a serialization, in polynomial time.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The circuit of a formula on n inputs, in polynomial time.
Equations
- One or more equations did not get rendered due to their size.