Skip to main content

nibli_semantics/
ir.rs

1//! First-Order Logic intermediate representation.
2//!
3//! Defines [`IrTerm`] (atomic terms) and [`IrForm`] (well-formed formulas)
4//! that the semantic compiler produces from the `AstBuffer` the nibli-kr
5//! emitter builds. The reasoning engine consumes these via the flattener in
6//! `lib.rs`.
7//!
8//! INTERN-THEN-RESOLVE BOUNDARY: every name in this IR is a [`lasso::Spur`]
9//! key into the compiler's per-compilation `Rodeo` — Spurs NEVER survive into
10//! `LogicBuffer`. `flatten_form` (lib.rs) resolves each Spur to an owned
11//! `String` at the flattening boundary, so nibli-reason and everything
12//! downstream see only strings. Variable identity is the `$`-prefixed
13//! interned string — the sigil survives interning, and the free-variable and
14//! scope-marker passes key on it.
15
16use lasso::Spur;
17
18/// The atomic arguments of a predicate.
19#[derive(Debug, PartialEq, Clone)]
20pub enum IrTerm {
21    /// A bound logic variable (a `$`-prefixed name, e.g. `$x`)
22    Variable(Spur),
23    /// A named constant entity (a Name like `Adam`, or a pronoun constant)
24    Constant(Spur),
25    /// An entity described by a predicate (`some dog` / `the dog`)
26    Description(Spur),
27    /// An explicitly unspecified argument (`_` or an omitted place)
28    Unspecified,
29    /// Numeric literal.
30    Number(f64),
31}
32
33/// The Well-Formed Formulas (WFFs) of our First-Order Logic engine.
34#[derive(Debug, PartialEq, Clone)]
35pub enum IrForm {
36    /// An n-ary predicate: P(t1, t2, ..., tn)
37    Predicate { relation: Spur, args: Vec<IrTerm> },
38    /// Universal quantification: ∀x. P(x)
39    ForAll(Spur, Box<IrForm>),
40    /// Existential quantification: ∃x. P(x)
41    Exists(Spur, Box<IrForm>),
42    /// Logical Conjunction: A ∧ B
43    And(Box<IrForm>, Box<IrForm>),
44    /// Logical Disjunction: A ∨ B
45    Or(Box<IrForm>, Box<IrForm>),
46    /// Logical Negation: ¬A
47    Not(Box<IrForm>),
48    /// Past tense wrapper (`past P`): P was true.
49    Past(Box<IrForm>),
50    /// Present tense wrapper (`now P`): P is true now.
51    Present(Box<IrForm>),
52    /// Future tense wrapper (`future P`): P will be true.
53    Future(Box<IrForm>),
54    /// Deontic obligation (`must P`): P ought to be true.
55    Obligatory(Box<IrForm>),
56    /// Deontic permission (`may P`): P is permitted.
57    Permitted(Box<IrForm>),
58    /// Exactly `count` distinct x satisfy `body`.
59    /// Count(var, count, body)
60    Count {
61        var: Spur,
62        count: u32,
63        body: Box<IrForm>,
64    },
65    /// Biconditional: A ↔ B  (expanded at flattening to And(Or(Not(A), B), Or(Not(B), A)))
66    Biconditional(Box<IrForm>, Box<IrForm>),
67    /// Exclusive or: A ⊕ B  (expanded at flattening to And(Or(A, B), Not(And(A, B))))
68    Xor(Box<IrForm>, Box<IrForm>),
69}