2 Monist Engine CLI User Guide
Welcome to the Monist Engine CLI! This guide will help you navigate the unified interactive REPL (Read-Eval-Print Loop) environment, which provides a modern, stateful experience for mathematical verification and Natural Deduction tactical proving.
2.1 Getting Started
To start the interactive session, simply run the CLI without any arguments:
cargo run -p monist-cli -- replYou will be greeted with a monist> prompt, ready to accept your commands.
2.2 Logic Parsing & Syntax Cheatsheet
Before diving into proofs, here is exactly how the monist-parser reads standard mathematical syntax:
- Variables & Predicates:
x,y,P(x),Q(a,b) - Logical Connectives:
- AND:
/\(e.g.,A /\ B) - OR:
\/(e.g.,A \/ B) - IMPLIES:
->(e.g.,A -> B) - NOT:
~(e.g.,~A) - IFF:
<->(e.g.,A <-> B)
- AND:
- Quantifiers:
- For All:
forall x. P(x) - Exists:
exists y. Q(y)
- For All:
- Set Theory Operations:
- Membership:
x in y - Equality:
x = y - Typestate Inequality:
x < y - Set Comprehension:
{x | P(x)}(e.g.,{x | ~(x in x)})
- Membership:
2.3 Interactive Tutorial: Proving Strong Cantorian Preservation
The best way to understand the REPL is through a canonical, continuous example. Let’s walk through how a user would interactively prove that the Quine pair preserves Strongly Cantorian (SC) sets.
2.3.1 1. Defining Axioms
First, we need to declare the foundational rules we are working with using assume <name> <formula>.
monist> assume SC_Def forall x. SC(x) <-> (x = T(x))
Assumed: SC_Def
monist> assume Quine_Flatness forall x y. typestate(Q(x,y)) == max(typestate(x), typestate(y))
Assumed: Quine_Flatness
Note: The system globally registers these named axioms for later retrieval or constraint evaluation.
2.3.2 2. Setting a Goal
We declare the theorem we want to prove using theorem <name> <formula>. This transitions the REPL into tactical proof mode.
monist> theorem SC_Preservation forall a b. (SC(a) /\ SC(b)) -> SC(Q(a,b))
[Goal Set] 1 unproven target.
2.3.3 3. Tactical Natural Deduction
We can use show_goal at any time to inspect the local Context (hypotheses) and Target. Let’s break down the logic using standard Natural Deduction tactics.
monist> intro a
monist> intro b
monist> intro H_SC
monist> destruct H_SC H1 H2
monist> show_goal
--- Context ---
H1: SC(a)
H2: SC(b)
--- Target ---
SC(Q(a,b))
The intro command brought our variables and implication premise into the context, and destruct cleanly split the H_SC conjunction into H1 and H2.
2.3.4 4. Rewriting
We use rewrite <name> to perform symbolic substitution based on equalities.
monist> rewrite SC_Def
[Goal Rewritten] Target 1 is now: Q(a,b) = T(Q(a,b))
monist> rewrite H1
monist> rewrite H2
[Goal Rewritten] Target 1 is now: Q(T(a), T(b)) = T(Q(a,b))
2.3.5 5. Diagnostics and Stratification
At this stage, we might want to hand off the topological heavy lifting to the internal geometric constraint engine. We can use the eval command to test if the formula successfully stratifies across the T-boundary!
monist> eval ((((((a = Ta /\ b = Tb) /\ Qab = a) /\ Qab = b) /\ QTaTb = Ta) /\ QTaTb = Tb) /\ QTaTb = TQab) /\ Qab = TQab
Stratification successful. Witness: {a@0 : 0, b@0 : 0, Ta@0 : 0, Tb@0 : 0, QTaTb@0 : 0, Qab@0 : 0, TQab@0 : 0}
The eval and step commands bypass the tactical proof state, instantly extracting topological constraints and running the Bellman-Ford cycle detection algorithm to verify mathematical consistency.
2.3.6 6. Managing the Session
You can save your progress mid-proof and load it back later:
monist> save_session my_proof.json
Session saved to my_proof.json.
monist> qed
Proof accepted.
2.4 Unified Command Reference
2.4.1 Core Proof Environment
help: Show the help message.exit/quit: Exit the REPL.save_session <file.json>: Save the current session (axioms and active goals) to a JSON file.load_session <file.json>: Load a previously saved session.
2.4.2 Axioms & Proofs
assume <name> <formula>: Register a named axiom into the global environment.theorem <name> <formula>: Start a new proof with a target goal and enter tactical mode.deff <name>(<args>) := <formula>: Define a macro with Kosaraju SCC pre-flattening, collapsing internal 0-weight edges into an optimized DAG to minimize topological evaluation overhead.show_goal: Print the active target goal and its local context/hypotheses (with De Bruijn scope tags intentionally hidden to minimize UI clutter).qed: Conclude an interactive proof if all goals are solved.abort: Cancel the current interactive proof.
2.4.3 Interactive Tactics
intro [name]: Introduce a premise or a universally quantified variable into the local context.exact <name>: Close the current goal if it exactly matches the specified hypothesis.apply <name>: Apply backward reasoning using an implication hypothesis.split: Split a conjunction (/\) goal into two separate sub-goals.left/right: Choose a side to prove for a disjunction (\/) goal.destruct <name> [n1] [n2]: Break down a hypothesis (like a conjunction or disjunction) into smaller pieces in the context.rewrite <name>: Substitute variables inside the goal based on an equality hypothesis.cut <formula>: Diagnostic Cut Tactic. Introduces a highly saturated formula as a sub-goal, allowing you to explicitly trigger Extensionality bounds.focus_hyp <name>: Pull a specific hypothesis to the top of your context array for easier visibility.defer: Skip the current active goal, sending it to the back of theProofStatequeue.
2.4.4 Diagnostic Evaluation
check_strat <formula>: An alias/sandbox command to run the AST parser and Bellman-Ford algorithm on raw geometry instantly before proofs.eval <formula>: Immediately test a formula for stratification loops and geometric friction without entering the tactical proof state.step <formula>: Process a logical formula step-by-step, providing immediate, color-coded feedback on topological friction and geometric bounds.
2.5 Troubleshooting Paradoxes
If the engine suddenly halts with an Extensionality Collision! Negative-weight cycle detected, do not panic. You have not broken the engine; you have merely asked a set to swallow itself while enforcing an incompatible typestate shift.
Here is how to untangle the structural topology of your proof:
- Kuratowski Cartesian Products: Are you constructing Cartesian products using traditional Kuratowski ordered pairs (\(\{\{x\}, \{x, y\}\}\))? Kuratowski pairs artificially force a \(+2\) typestate shift on your variables, much like growing too tall for the room. The geometric engine will flag this friction instantly. To fix this, switch your definitions to flat Quine pairs (\(Q(a,b)\)), which maintain a rigid \(0\)-weight shift, allowing your variables to stay exactly the same size.
- Universal Set Boundaries: If you are trying to map functions across the boundary of the Universal Set (\(V\)), you must step through the topological threshold. Attempting to bridge distinct integer typestate elevations without a stabilizer will cause the Bellman-Ford cycle detector to terminate your proof. You must explicitly invoke the \(T\)-operator (\(x \mapsto \iota"x\)) or rely on the engine’s automated
T-Functor Synthesisto gracefully absorb the topological friction. - Saturated Loops: If you are stuck in an infinite recursion, check if you accidentally defined an unstratified loop outside of a Strongly Cantorian boundary. Use the
stepcommand to visualize the \(K\)-Iteration depth bounds in real-time, observing exactly where the loop fails to terminate.
2.6 Understanding the Engine: Constraints and Tactics
To effectively use this dual-engine architecture, it is crucial to understand what the underlying Rust graph engine can “see,” and how to guide your tactical proofs to produce that specific geometry.
2.6.1 Geometric Constraints
The Bellman-Ford topological engine (eval / step) is incredibly fast, but its vocabulary is strictly limited to foundational set-theoretic boundaries. It translates formulas into a geometric Directed Acyclic Graph (DAG) using only the following atomic constraints:
- Equality (
x = y): Generates a0weight constraint. The engine mathematically locks the two variables at the exact same typestate level. - Membership (
x e y): Generates a+1weight constraint. The setymust exist at a typestate level strictly higher than its elementx. - Function Application (
z = u(v)): Generates a+1weight constraint. The functionumust be typed one level higher than the argumentv. - Lambda Abstraction (
z = \lambda x. t): Generates a+1weight constraint. The abstracted function body sits one level higher than the variable it binds. - Quine Pairs (
Q(a,b)): Generates0weight constraints. Unlike standard Kuratowski pairs (which force a+2type shift), Quine pairs are geometrically “flat.” - Strict Typestate Offset (
x < y): Generates a-1weight constraint. The variablexmust be strictly lower in typestate elevation thany(\(x \le y - 1\)). - Set Comprehension (
{x | P(x)}): Generates a+1weight constraint boundary. The internal formula \(P(x)\) is forced to exist one topological level lower than the set defined by the comprehension. If a \(+1\) shift topological cycle spans across this boundary (i.e.in_comp == true), it is recognized as a mathematical paradox and strictly rejected, whereas free-floating cycles outside of comprehensions may be isolated as Strongly Cantorian bedrock.
2.6.2 The Tactical Workflow
When staring at a high-level mathematical theorem, your goal as the user is to act as the “compiler,” using tactics to translate human semantics down into the raw spatial constraints listed above.
- Strip the Logical Scaffolding: The geometric engine evaluates spatial structures, not conditional hypotheticals. Use
introto strip awayforallquantifiers and pullIfpremises down into your local Context as usable facts. Usedestructto break complex conjunctions (/\) into isolated facts. - Unfold Semantic Definitions: The graph engine cannot read abstract properties like “Strongly Cantorian” or “Ordinal.” Use
rewrite(alongside your globalassumeaxioms) to unfold these abstractions into raw set theory (e.g., rewritingSC(x)tox = T(x)). - Isolate the Friction: Use
rewriteto substitute variables across your equalities until the core components of your target goal are expressed purely in terms of raw variables connected by=ore. You want to find the exact boundary where the theorem forces a variable to cross a typestate level. - The Topological Handoff: Once your
ProofStatehas been entirely stripped of implications, quantifiers, and abstract names, you gather the surviving structural equations and feed them intoeval. The graph engine will instantly compute if that raw geometry can safely exist in finite computational space, or if it collapses into a negative-weight cycle (a paradox).
2.7 One-Shot Commands
You can still use the CLI in traditional one-shot mode for scripting or quick checks outside the REPL.
2.7.1 verify <formula>
Quickly evaluates a formula.
cargo run -p monist-cli -- verify "x = y"2.7.2 export-smt <formula>
Generates a StratificationWitness trace in standard SMT-LIB format for external theorem provers (like Z3 or CVC5).
cargo run -p monist-cli -- export-smt "x in y /\ y in z /\ z in x" > trace.smt22.8 Under the Hood: REPL Tactic Integration
The interactive REPL is not just a semantic parser; it actively bridges Natural Deduction to the CPU Geometry layer. We can observe this programmatic handoff in tools/monist-examples/src/bin/repl_tactic_integration.rs.
When tactics are executed (intro, rewrite, destruct), the human interface manipulates an underlying FormulaArena.
let mut parser = Parser::new(formula, &mut self.arena);
let root_idx = parser.parse_formula();
// Extract the topological matrix
let constraints = extract_constraints_aux(&self.arena, root_idx, 0, false);
self.graph = GraphArena::from_constraints(&constraints);When you query for a diagnostic limit (eval or step), the engine collapses 0-weight sub-graphs (equalities) using Kosaraju’s SCC algorithm and tests the geometry:
self.graph.collapse_scc_0_weight();
if let Some(limits) = ExecutionLimits::compute_for_graph(&self.graph) {
println!("Execution Limits Computed: MCM = {:.2}", limits.mcm);
}This effectively translates abstract set properties—like SC_Preservation—into absolute mathematical bounds tracking typestate differentials, automatically rejecting invalid topological matrices before combinator compilation.