Boolean formulas and their circuits #
A formula (Fml) is a tree of and, or, not over input bits and constants. Its
post-order flattening (Fml.flattenAt) is a circuit in which every gate is read at most once
(input bits are read through fresh input gates, which Circuit.WellFormed does not count),
so a formula's circuit is well-formed whatever the formula (Fml.toCircuit_wellFormed), and
computes the formula (Fml.eval_toCircuit). The describer of the succinct Cook–Levin
theorem is built as a formula, which confines the circuit bookkeeping to this file
(planning/succinct-cook-levin.md, S3).
Equations
- One or more equations did not get rendered due to their size.
- MIPRE.SAT.instDecidableEqFml.decEq (MIPRE.SAT.Fml.inp a) (MIPRE.SAT.Fml.inp b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (MIPRE.SAT.Fml.inp i) (MIPRE.SAT.Fml.const b) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (MIPRE.SAT.Fml.inp i) (f.and g) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (MIPRE.SAT.Fml.inp i) (f.or g) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (MIPRE.SAT.Fml.inp i) f.not = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (MIPRE.SAT.Fml.const b) (MIPRE.SAT.Fml.inp i) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (MIPRE.SAT.Fml.const a) (MIPRE.SAT.Fml.const b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (MIPRE.SAT.Fml.const b) (f.and g) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (MIPRE.SAT.Fml.const b) (f.or g) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (MIPRE.SAT.Fml.const b) f.not = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (f.and g) (MIPRE.SAT.Fml.inp i) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (f.and g) (MIPRE.SAT.Fml.const b) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (f.and g) (f_1.or g_1) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (f.and g) f_1.not = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (f.or g) (MIPRE.SAT.Fml.inp i) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (f.or g) (MIPRE.SAT.Fml.const b) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (f.or g) (f_1.and g_1) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq (f.or g) f_1.not = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq f.not (MIPRE.SAT.Fml.inp i) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq f.not (MIPRE.SAT.Fml.const b) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq f.not (f_1.and g) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq f.not (f_1.or g) = isFalse ⋯
- MIPRE.SAT.instDecidableEqFml.decEq a.not b.not = if h : a = b then h ▸ have inst := MIPRE.SAT.instDecidableEqFml.decEq a a; isTrue ⋯ else isFalse ⋯
Instances For
Equations
- MIPRE.SAT.instReprFml = { reprPrec := MIPRE.SAT.instReprFml.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
The value of a formula on the input bits x.
Equations
- MIPRE.SAT.Fml.eval x (MIPRE.SAT.Fml.inp i) = x i
- MIPRE.SAT.Fml.eval x (MIPRE.SAT.Fml.const b) = b
- MIPRE.SAT.Fml.eval x (f.and g) = (MIPRE.SAT.Fml.eval x f && MIPRE.SAT.Fml.eval x g)
- MIPRE.SAT.Fml.eval x (f.or g) = (MIPRE.SAT.Fml.eval x f || MIPRE.SAT.Fml.eval x g)
- MIPRE.SAT.Fml.eval x f.not = !MIPRE.SAT.Fml.eval x f
Instances For
Every input bit read is below n.
Equations
- MIPRE.SAT.Fml.InputsLt n (MIPRE.SAT.Fml.inp i) = (i < n)
- MIPRE.SAT.Fml.InputsLt n (MIPRE.SAT.Fml.const b) = True
- MIPRE.SAT.Fml.InputsLt n (f.and g) = (MIPRE.SAT.Fml.InputsLt n f ∧ MIPRE.SAT.Fml.InputsLt n g)
- MIPRE.SAT.Fml.InputsLt n (f.or g) = (MIPRE.SAT.Fml.InputsLt n f ∧ MIPRE.SAT.Fml.InputsLt n g)
- MIPRE.SAT.Fml.InputsLt n f.not = MIPRE.SAT.Fml.InputsLt n f
Instances For
Formulas as data: the post-order serialization #
Equations
- MIPRE.SAT.Fml.instDecidableEqNode.decEq (MIPRE.SAT.Fml.Node.inp a) (MIPRE.SAT.Fml.Node.inp b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq (MIPRE.SAT.Fml.Node.inp i) (MIPRE.SAT.Fml.Node.const b) = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq (MIPRE.SAT.Fml.Node.inp i) MIPRE.SAT.Fml.Node.and = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq (MIPRE.SAT.Fml.Node.inp i) MIPRE.SAT.Fml.Node.or = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq (MIPRE.SAT.Fml.Node.inp i) MIPRE.SAT.Fml.Node.not = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq (MIPRE.SAT.Fml.Node.const b) (MIPRE.SAT.Fml.Node.inp i) = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq (MIPRE.SAT.Fml.Node.const a) (MIPRE.SAT.Fml.Node.const b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq (MIPRE.SAT.Fml.Node.const b) MIPRE.SAT.Fml.Node.and = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq (MIPRE.SAT.Fml.Node.const b) MIPRE.SAT.Fml.Node.or = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq (MIPRE.SAT.Fml.Node.const b) MIPRE.SAT.Fml.Node.not = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.and (MIPRE.SAT.Fml.Node.inp i) = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.and (MIPRE.SAT.Fml.Node.const b) = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.and MIPRE.SAT.Fml.Node.and = isTrue ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.and MIPRE.SAT.Fml.Node.or = isFalse MIPRE.SAT.Fml.instDecidableEqNode.decEq._proof_15
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.and MIPRE.SAT.Fml.Node.not = isFalse MIPRE.SAT.Fml.instDecidableEqNode.decEq._proof_16
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.or (MIPRE.SAT.Fml.Node.inp i) = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.or (MIPRE.SAT.Fml.Node.const b) = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.or MIPRE.SAT.Fml.Node.and = isFalse MIPRE.SAT.Fml.instDecidableEqNode.decEq._proof_19
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.or MIPRE.SAT.Fml.Node.or = isTrue ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.or MIPRE.SAT.Fml.Node.not = isFalse MIPRE.SAT.Fml.instDecidableEqNode.decEq._proof_20
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.not (MIPRE.SAT.Fml.Node.inp i) = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.not (MIPRE.SAT.Fml.Node.const b) = isFalse ⋯
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.not MIPRE.SAT.Fml.Node.and = isFalse MIPRE.SAT.Fml.instDecidableEqNode.decEq._proof_23
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.not MIPRE.SAT.Fml.Node.or = isFalse MIPRE.SAT.Fml.instDecidableEqNode.decEq._proof_24
- MIPRE.SAT.Fml.instDecidableEqNode.decEq MIPRE.SAT.Fml.Node.not MIPRE.SAT.Fml.Node.not = isTrue ⋯
Instances For
Equations
- One or more equations did not get rendered due to their size.
- MIPRE.SAT.Fml.instReprNode.repr MIPRE.SAT.Fml.Node.and prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "MIPRE.SAT.Fml.Node.and")).group prec✝
- MIPRE.SAT.Fml.instReprNode.repr MIPRE.SAT.Fml.Node.or prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "MIPRE.SAT.Fml.Node.or")).group prec✝
- MIPRE.SAT.Fml.instReprNode.repr MIPRE.SAT.Fml.Node.not prec✝ = Repr.addAppParen (Std.Format.nest (if prec✝ ≥ 1024 then 1 else 2) (Std.Format.text "MIPRE.SAT.Fml.Node.not")).group prec✝
Instances For
Equations
- MIPRE.SAT.Fml.instReprNode = { reprPrec := MIPRE.SAT.Fml.instReprNode.repr }
Equations
Nodes as data: a unary tag and the payload.
Equations
- (MIPRE.SAT.Fml.Node.inp i).toData = (MIPRE.Cost.Data.ofNat 0).cons (MIPRE.Cost.encode i)
- (MIPRE.SAT.Fml.Node.const b).toData = (MIPRE.Cost.Data.ofNat 1).cons (MIPRE.Cost.encode b)
- MIPRE.SAT.Fml.Node.and.toData = (MIPRE.Cost.Data.ofNat 2).cons MIPRE.Cost.Data.nil
- MIPRE.SAT.Fml.Node.or.toData = (MIPRE.Cost.Data.ofNat 3).cons MIPRE.Cost.Data.nil
- MIPRE.SAT.Fml.Node.not.toData = (MIPRE.Cost.Data.ofNat 4).cons MIPRE.Cost.Data.nil
Instances For
Decoding nodes.
Equations
- One or more equations did not get rendered due to their size.
- MIPRE.SAT.Fml.Node.ofData? (MIPRE.Cost.Data.nil.cons p) = Option.map MIPRE.SAT.Fml.Node.inp (MIPRE.Cost.decode p)
- MIPRE.SAT.Fml.Node.ofData? ((MIPRE.Cost.Data.nil.cons MIPRE.Cost.Data.nil).cons p) = Option.map MIPRE.SAT.Fml.Node.const (MIPRE.Cost.decode p)
- MIPRE.SAT.Fml.Node.ofData? ((MIPRE.Cost.Data.nil.cons (MIPRE.Cost.Data.nil.cons MIPRE.Cost.Data.nil)).cons MIPRE.Cost.Data.nil) = some MIPRE.SAT.Fml.Node.and
- MIPRE.SAT.Fml.Node.ofData? ((MIPRE.Cost.Data.nil.cons (MIPRE.Cost.Data.nil.cons (MIPRE.Cost.Data.nil.cons MIPRE.Cost.Data.nil))).cons MIPRE.Cost.Data.nil) = some MIPRE.SAT.Fml.Node.or
- MIPRE.SAT.Fml.Node.ofData? x✝ = none
Instances For
Equations
- MIPRE.SAT.Fml.Node.instSizedEncoding = { encode := MIPRE.SAT.Fml.Node.toData, decode := MIPRE.SAT.Fml.Node.ofData?, decode_encode := MIPRE.SAT.Fml.Node.ofData?_toData }
The post-order serialization of a formula.
Equations
Instances For
One step of parsing a post-order serialization with a stack of formulas (a malformed input leaves the stack unchanged).
Equations
- MIPRE.SAT.Fml.parseStep st (MIPRE.SAT.Fml.Node.inp i) = MIPRE.SAT.Fml.inp i :: st
- MIPRE.SAT.Fml.parseStep st (MIPRE.SAT.Fml.Node.const b) = MIPRE.SAT.Fml.const b :: st
- MIPRE.SAT.Fml.parseStep (g :: f :: st_2) MIPRE.SAT.Fml.Node.and = f.and g :: st_2
- MIPRE.SAT.Fml.parseStep st MIPRE.SAT.Fml.Node.and = st
- MIPRE.SAT.Fml.parseStep (g :: f :: st_2) MIPRE.SAT.Fml.Node.or = f.or g :: st_2
- MIPRE.SAT.Fml.parseStep st MIPRE.SAT.Fml.Node.or = st
- MIPRE.SAT.Fml.parseStep (f :: st_2) MIPRE.SAT.Fml.Node.not = f.not :: st_2
- MIPRE.SAT.Fml.parseStep st MIPRE.SAT.Fml.Node.not = st
Instances For
Parsing a post-order serialization.
Equations
- MIPRE.SAT.Fml.parse l = match List.foldl MIPRE.SAT.Fml.parseStep [] l with | [f] => some f | x => none
Instances For
Formulas encode as their post-order serializations, so that a program builds a formula by appending lists.
Equations
- One or more equations did not get rendered due to their size.
The serialization, as a polynomial-time function (the encoding is the same).
Equations
Instances For
The constructors as polynomial-time functions.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Flattening to a circuit #
The post-order gate list of a formula whose first gate is at position base: the output
gate is the last one, at base + size - 1.
Equations
- MIPRE.SAT.Fml.flattenAt base (MIPRE.SAT.Fml.inp i) = [MIPRE.SAT.Gate.input i]
- MIPRE.SAT.Fml.flattenAt base (MIPRE.SAT.Fml.const b) = [MIPRE.SAT.Gate.const b]
- MIPRE.SAT.Fml.flattenAt base (f.and g) = MIPRE.SAT.Fml.flattenAt base f ++ MIPRE.SAT.Fml.flattenAt (base + f.size) g ++ [MIPRE.SAT.Gate.and (base + f.size - 1) (base + f.size + g.size - 1)]
- MIPRE.SAT.Fml.flattenAt base (f.or g) = MIPRE.SAT.Fml.flattenAt base f ++ MIPRE.SAT.Fml.flattenAt (base + f.size) g ++ [MIPRE.SAT.Gate.or (base + f.size - 1) (base + f.size + g.size - 1)]
- MIPRE.SAT.Fml.flattenAt base f.not = MIPRE.SAT.Fml.flattenAt base f ++ [MIPRE.SAT.Gate.not (base + f.size - 1)]
Instances For
The circuit of a formula on n inputs.
Equations
- MIPRE.SAT.Fml.toCircuit n f = { inputs := n, gates := MIPRE.SAT.Fml.flattenAt 0 f }
Instances For
The number of references to u in a gate list.
Equations
- MIPRE.SAT.Fml.refCount gs u = (List.map (fun (g : MIPRE.SAT.Gate) => List.count u g.refs) gs).sum
Instances For
The circuit of a formula is well-formed.