The circuit value problem: definition #
CVP asks whether a Boolean circuit, given with the values of its input gates,
evaluates its designated output gate to true. It is the canonical
PTIME-complete problem of the textbooks (Ladner 1975),
and the natural companion of HORN-SAT one level below Cook–Levin: where
HORN-SAT is the syntactic image of the Horn fragment, CVP is the syntactic
image of evaluation.
The vocabulary #
FirstOrder.Language.circuit marks each element with its kind – a constant
input (circIsTrue, circIsFalse), a gate (circIsAnd, circIsOr,
circIsNot), the output (circOut) – and wires gates to their arguments with
two binary relations circLeft and circRight, a negation using circLeft
alone. Fan-in is therefore two, as in the standard statement; unbounded fan-in
would put an iterated conjunction in the semantics, where this library
prefers to keep it in a reduction that walks an order.
The semantics, and why nothing is assumed about the instance #
The value of a gate is defined by the least dual-rail derivation
(DescriptiveComplexity.GateVal, one inductive family indexed by the value
being derived): GateVal true g and GateVal false g say that the value 1,
respectively 0, is derivable at g from the constant inputs by the gate
rules. A yes-instance is one whose output gate derives true
(DescriptiveComplexity.CircuitAccepts).
Three degeneracies are then harmless, and none needs a well-formedness hypothesis:
- junk – an element marked with no kind at all derives nothing, so it can neither make the output true nor prevent it;
- cycles – a gate on a cycle simply derives no value, the derivation being a least fixed point rather than a recursion, so the problem stays a total predicate on arbitrary finite structures with no acyclicity condition to carry (and, unlike acyclicity, no condition that is not first-order);
- malformed gates – an element marked both
circIsAndandcircIsOr, or wired to two left arguments, may derive both values; that makes it a yes-instance of nothing in particular, not an ill-defined one.
On a well-formed acyclic circuit the derivable value is the value, which is all
the reduction of DescriptiveComplexity.Problems.Cvp.Hardness needs, since the
circuit it builds is well-formed and acyclic by construction.
Folding no condition into the yes-instances is the same choice as for 3SAT's
width bound and HORN-SAT's Horn condition made in reverse, and for the same
reason: it keeps CVP a decision problem on arbitrary Language.circuit
structures, so that it lives in the same catalog and composes with the same
reductions.
Dependency graph
isNot g: the element g is a negation gate, its argument read off
left.
Instances For
Dependency graph
Dependency graph
The relational language of Boolean circuits: one unary predicate per gate kind, one marking the output, and two binary predicates wiring a gate to its arguments.
Equations
- FirstOrder.Language.circuit = { Functions := fun (x : ℕ) => Empty, Relations := FirstOrder.Language.circuitRel }
Instances For
Dependency graph
Dependency graph
The relation symbols of the language.
- isTrue : circuitRel 1
isTrue g: the elementgis a constant input gate holding1. - isFalse : circuitRel 1
isFalse g: the elementgis a constant input gate holding0. - isAnd : circuitRel 1
isAnd g: the elementgis a conjunction gate. - isOr : circuitRel 1
isOr g: the elementgis a disjunction gate. - isNot : circuitRel 1
- out : circuitRel 1
out g: the elementgis an output gate. - left : circuitRel 2
left g x: the gategtakesxas its first argument. - right : circuitRel 2
right g x: the gategtakesxas its second argument.
Instances For
Dependency graph
Equations
- One or more equations did not get rendered due to their size.
- FirstOrder.Language.instDecidableEqCircuitRel.decEq FirstOrder.Language.circuitRel.out FirstOrder.Language.circuitRel.out = isTrue FirstOrder.Language.instDecidableEqCircuitRel.decEq._proof_36
Instances For
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
The value derivable at a gate, as one inductive family indexed by the
value being derived: GateVal true g says that g evaluates to 1,
GateVal false g that it evaluates to 0. Being an inductive predicate, it is
the least pair of rails closed under the gate rules, so a gate whose
arguments derive nothing – including one on a cycle – derives nothing.
The rules are the usual ones read in both polarities: a conjunction is true when both arguments are, false as soon as one is; a disjunction dually; a negation swaps the rails.
- constTrue
{A : Type}
[FirstOrder.Language.circuit.Structure A]
{g : A}
(h : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circIsTrue ![g])
: GateVal true g
A constant
1input derivestrue. - constFalse
{A : Type}
[FirstOrder.Language.circuit.Structure A]
{g : A}
(h : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circIsFalse ![g])
: GateVal false g
A constant
0input derivesfalse. - andTrue
{A : Type}
[FirstOrder.Language.circuit.Structure A]
{g l r : A}
(hg : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circIsAnd ![g])
(hl : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circLeft ![g, l])
(hr : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circRight ![g, r])
(vl : GateVal true l)
(vr : GateVal true r)
: GateVal true g
A conjunction with both arguments true derives
true. - andFalseLeft
{A : Type}
[FirstOrder.Language.circuit.Structure A]
{g l : A}
(hg : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circIsAnd ![g])
(hl : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circLeft ![g, l])
(vl : GateVal false l)
: GateVal false g
A conjunction with a false first argument derives
false. - andFalseRight
{A : Type}
[FirstOrder.Language.circuit.Structure A]
{g r : A}
(hg : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circIsAnd ![g])
(hr : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circRight ![g, r])
(vr : GateVal false r)
: GateVal false g
A conjunction with a false second argument derives
false. - orTrueLeft
{A : Type}
[FirstOrder.Language.circuit.Structure A]
{g l : A}
(hg : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circIsOr ![g])
(hl : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circLeft ![g, l])
(vl : GateVal true l)
: GateVal true g
A disjunction with a true first argument derives
true. - orTrueRight
{A : Type}
[FirstOrder.Language.circuit.Structure A]
{g r : A}
(hg : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circIsOr ![g])
(hr : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circRight ![g, r])
(vr : GateVal true r)
: GateVal true g
A disjunction with a true second argument derives
true. - orFalse
{A : Type}
[FirstOrder.Language.circuit.Structure A]
{g l r : A}
(hg : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circIsOr ![g])
(hl : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circLeft ![g, l])
(hr : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circRight ![g, r])
(vl : GateVal false l)
(vr : GateVal false r)
: GateVal false g
A disjunction with both arguments false derives
false. - notTrue
{A : Type}
[FirstOrder.Language.circuit.Structure A]
{g i : A}
(hg : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circIsNot ![g])
(hi : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circLeft ![g, i])
(vi : GateVal false i)
: GateVal true g
A negation with a false argument derives
true. - notFalse
{A : Type}
[FirstOrder.Language.circuit.Structure A]
{g i : A}
(hg : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circIsNot ![g])
(hi : FirstOrder.Language.Structure.RelMap FirstOrder.Language.circLeft ![g, i])
(vi : GateVal true i)
: GateVal false g
A negation with a true argument derives
false.
Instances For
Dependency graph
A Language.circuit-structure is a yes-instance when some output gate
derives the value 1.
Equations
Instances For
Dependency graph
Isomorphism-invariance and the bundled problem #
Acceptance is isomorphism-invariant.
Dependency graph
CVP, the circuit value problem, as a problem on
Language.circuit-structures: does the output gate derive the value 1?
Equations
- DescriptiveComplexity.CVP = { Holds := fun (A : Type) (inst : FirstOrder.Language.circuit.Structure A) => DescriptiveComplexity.CircuitAccepts A, iso_invariant := ⋯ }