Skip to main content

g6-formal

Use when an answer rests on a logical step that must be exactly right, such as whether premises entail a conclusion, whether constraints can all hold, a counterexample to a claim, two conditions being equivalent, which requirements conflict, or a small optimum over integer or real constraints, and you are about to argue it in words instead of deciding it.

Source facts

Repository
basicisabc1994/g6solver
Last source activity
October 30, 2026 at 10:47
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
g6-formal
description
Use when an answer rests on a logical step that must be exactly right, such as whether premises entail a conclusion, whether constraints can all hold, a counterexample to a claim, two conditions being equivalent, which requirements conflict, or a small optimum over integer or real constraints, and you are about to argue it in words instead of deciding it.
# G6 formal Decides logic questions exactly, in process: Z3 on SMT-LIB terms over symbols you declare, a pure-Python DPLL for Boolean formulas, and Belnap's four-valued logic with modal frames. The answers of `optimise`, `unsat_core`, `simplify`, `eliminate_quantifiers` and `count_models` are checked again on fresh solvers; a validity check also asks whether its premises can hold; every decision records the exact queries it rests on, which `g6.formal.recheck` can run again. ## When to use it - You are about to write "this follows", "these rules cannot conflict", "this guard is always true" or "no input breaks it". - A review hinges on a condition: two guards equivalent, a branch unreachable, a bound that always holds. - Requirements seem to conflict and you need the smallest conflicting set. - You want a concrete counterexample to a claim, not an argument. ## When not to use it - Algebra or calculus (simplify, solve, integrate): use `algebra`. - Everything that facts and rules derive: use `datalog`; with graded truth values, `graph_reasoning`. - A state machine over many steps (invariants, deadlocks): use `model_checking`, which reads its terms through this package's grammar. - Linear, integer, routing or scheduling problems of real size: use `optimisation`; `optimise` here is for small symbolic objectives. - A claim in prose that rests on sources: use `grounding` or `epistemic_integrity`. This component decides only the encoding you write. ## Ops - `check_contract`: checks up to 32 `properties` (SMT terms) against `premises` and `sorts`, then aggregates with Belnap conjunction. Missing properties refuse by default; non-vacuity cannot be switched off. With premises, a property that holds is checked again without them: one that holds alone is N (`G6_E_FORMAL_VACUOUS_PROPERTY`). `timeout` is one deadline for the whole call: each check gets the time that remains (a validity check, which can run two queries, half of it), and running out is N with `G6_E_FORMAL_SOLVER_TIMEOUT`. - `check_sat`: whether `formula` with `assertions` can hold over the declared `sorts`, with a model. - `check_validity`: whether `premises` entail `formula`: valid, `vacuous` (the premises cannot hold), circular (every conjunct of the conclusion appears literally among the premises), or a counterexample. - `check_entailment`: whether `formula` entails `other`. - `find_counterexample`: a model in which the claim `formula` is false while the `premises` hold. - `check_propositional`: a Boolean formula (`A & ~B`) with `assertions`, decided by the built-in DPLL; no Z3 needed. - `optimise`: the lexicographic optimum of `objectives` (`[["minimise", term]]` or `maximise`) under `assertions` and `bounds`, confirmed by a bound and an attainment check. - `unsat_core`: which of the `named` assertions conflict, shrunk to a minimal core (`minimal` says whether it was). - `simplify`: Z3's simplified term, confirmed equivalent. - `eliminate_quantifiers`: an equivalent quantifier-free formula. - `count_models`: how many models over the declared symbols, exact or at least `cap`. - `check_equivalence`: whether `formula` and `other` are equivalent under `premises`, or a distinguishing assignment. - `belnap_eval`: the four-valued value of a formula under `values` (`T`, `F`, `B` for both, `N` for neither). - `belnap_table`: the four-valued truth table over the formula's atoms. - `modal_eval`: necessity or possibility (`modality`) at `world` over a Kripke frame of `worlds` and `access`. - `frame_check`: which conditions of an alethic, epistemic, deontic or temporal `modal_frame` the `worlds` and `access` meet and miss, with a witness. ## Reading the result Terms are SMT-LIB, such as `(and (> x 2) (< x 4))`, over symbols declared in `sorts` (`Int`, `Real`, `Bool`, `String`, `(_ BitVec n)`, `(Array S T)`); nothing is declared for you. A decision is `qualified-draft` with `G6_E_FORMAL_SOLVER_DECISION` on `warning_card.code` (the result's own `code` is empty), and `artifact.checks` holds the queries the decision rests on, with Z3's answers (`optimise` adds `attainment`, `unsat_core` adds `minimality`), so anyone can run them again (`g6.formal.recheck` does). `blocked-escalated` codes, on `code` and the card, include `G6_E_FORMAL_VACUOUS_PREMISES`, `G6_E_FORMAL_CONCLUSION_ASSUMED`, `G6_E_FORMAL_SOLVER_UNKNOWN` and `G6_E_FORMAL_SOLVER_TIMEOUT` (unknown is never read as a decision), `G6_E_FORMAL_CERTIFICATE_REFUTED` and `G6_E_FORMAL_PARSE_ERROR`. A four-valued claim that comes out `F`, `B` or `N` is `blocked-escalated` (`G6_E_FORMAL_CLAIM_REFUTED`, `G6_E_FORMAL_CLAIM_CONFLICT`, `G6_E_FORMAL_CLAIM_UNKNOWN`), the value kept. ## Alone and composed Alone, over MCP: `g6_invoke("formal", "find_counterexample", params_json)`. From Python: `from g6.formal import check_sat, check_validity, find_counterexample, optimise`. Composed: - `model_checking` reads its state models through this package's closed grammar and checks them with Z3. - `cegis`'s `Z3Verifier` asks `g6.formal.check_sat` for an input on which a synthesised candidate breaks your spec. - Before reporting a conclusion that rests on a decision, give `coding_agent_gate`'s `verify_answer` the reply as an evidence item of kind `log`; it counts as caller-declared. ## Failure modes it catches - `confident_reasoning_error` (a reasoning slip stated with confidence): the step is decided by Z3 or DPLL instead of argued. A validity check also asks whether the premises can hold at all, so contradictory premises come back `vacuous`, not `valid`, and a conclusion whose every conjunct appears literally among the premises is flagged as circular. The depth ops' answers are checked again on fresh solvers (an optimum shown unbeaten and attained, a core shrunk until minimal, a simplified term shown equivalent, a model count shown exact); an answer its own check contradicts is refused. - `vacuous_proof`: an empty contract, inconsistent premises, a property that holds without the premises, a missing solver or a failed property cannot yield T. Contract evidence retains every property's solver checks and counterexample. Jointly inconsistent property formulas surface as B; a false property with a consistent specification is F. Neither is a proof. ## Blind spots - Contract properties are simultaneous requirements. A B conflict is a conflict in the specification, not conflicting real-world observations. Per-property timeouts can accumulate across the bounded list. - The encoding is yours. If the SMT-LIB does not say what the claim in words says, the decision does not either; G6 does not translate prose into logic or check that a translation is faithful. - Z3 can answer unknown or run out of time, especially on non-linear arithmetic and quantifiers; that is a refusal, not an answer. - `count_models` is a lower bound when it reaches `cap`. - `check_sat`, `check_validity`, `check_entailment`, `find_counterexample` and `check_equivalence` report one Z3 decision, not checked again on a second solver. - A core of more than 50 members is not shrunk, and a shrink query Z3 answers unknown leaves `minimal` null: the core may then hold more than the conflict needs. - Circularity is caught only literally: a conclusion that is a rewording of a premise is not flagged. - A Boolean formula whose CNF would pass the DPLL's clause limit is refused (`G6_E_FORMAL_INPUT_TOO_LARGE`; from `dpll_solve`, `FormulaTooLarge`), since distribution into CNF can grow exponentially. - A four-valued result is only as good as the values you assign each atom. ## What it needs - `pip install "g6[formal] @ git+https://github.com/basicisabc1994/g6solver"` for Z3 (`z3-solver`), imported only when a check runs. Without it every Z3 op is `blocked-escalated` with `G6_E_FORMAL_SOLVER_UNAVAILABLE` and the install line. - No outside program: `check_propositional` and the four-valued and modal ops are pure Python. No op runs code, writes a file or reaches the network, so none is sensitive. ## Examples ```g6-example op=check_contract {"properties":["(> x 0)","(< x 10)"],"premises":["(= x 4)"],"sorts":{"x":"Int"}} ``` ```g6-example op=find_counterexample {"formula": "(> (* x x) x)", "premises": ["(> x -5)", "(< x 5)"], "sorts": {"x": "Int"}} ``` The claim "x squared is greater than x" is false here: the reply is `qualified-draft`, `valid` is false and `counterexample` gives an `x` where it fails, with the query Z3 decided in `artifact.checks`. ```g6-example op=check_validity {"premises": ["(> x 1)", "(< x 0)"], "formula": "(> x 5)", "sorts": {"x": "Int"}} ``` The premises cannot both hold, so the reply is `blocked-escalated` with `G6_E_FORMAL_VACUOUS_PREMISES` and `vacuous` true: "valid" would mean nothing here. ```python from g6.formal import check_propositional, check_validity valid = check_validity(["(> x 1)"], "(> x 0)", sorts={"x": "Int"}) assert valid.valid and not valid.vacuous and valid.completion_state == "qualified-draft" assert check_propositional("A & ~B", assertions=["B | C"]).satisfiable is True ``` ## The four open problems - **Learning signals.** Not yet: it writes nothing to a run ledger itself. Each catch is a labelled result with its own `G6_E_FORMAL_*` code and the exact queries in `evidence`; recording it is the caller's step today. - **Evaluators the model cannot influence.** The decision is Z3's or the package's own DPLL, and the vacuity check and the depth ops' re-checks are the package's own code. No model call runs anywhere in the package; the caller writes the encoding, never the check. - **Transfer by failure mode.** The checks belong to the logic, not to a task: vacuity, circularity and the depth ops' re-checks apply to any encoding. Not yet: its catch rate on task families it was not built on has not been measured. - **Enough held-out cases.** Not yet: its own catch rate and false-alarm rate are not judged by a sequential test. A repeated workflow that uses it can be tuned with `g6.metaharness`, whose gate judges a change on held-out cases.
View on GitHub