Skip to main content

warp_types_smt/
phase.rs

1//! SMT solver phase markers.
2//!
3//! Zero-sized types encoding the SMT solving workflow. Sealed —
4//! external crates cannot forge phases or create invalid transitions.
5//!
6//! # Phase machine
7//!
8//! ```text
9//!   Init
10//!     → declare_sort(), declare_fun()   stays Init (accumulates declarations)
11//!     → finish_declarations()           → Declared
12//!   Declared
13//!     → assert_formula()                stays Declared (accumulates assertions)
14//!     → finish_assertions()             → Asserted
15//!   Asserted
16//!     → check_sat()                     → SmtResult
17//!       → Sat                             terminal: satisfiable model exists
18//!       → Unsat                           terminal: no model exists
19//!       → Unknown                         terminal: solver budget exhausted
20//! ```
21
22// ============================================================================
23// Sealed trait
24// ============================================================================
25
26pub(crate) mod sealed {
27    pub(crate) struct SealToken;
28
29    #[allow(private_interfaces)]
30    pub trait Sealed {
31        #[doc(hidden)]
32        fn _sealed() -> SealToken;
33    }
34}
35
36// ============================================================================
37// Phase trait + markers
38// ============================================================================
39
40/// Marker trait for SMT phases. Sealed.
41pub trait Phase: sealed::Sealed + 'static {
42    /// Human-readable phase name.
43    const NAME: &'static str;
44}
45
46/// Initial state — declare sorts and function symbols.
47#[derive(Debug)]
48pub struct Init;
49
50/// Declarations finalized — assert formulas.
51#[derive(Debug)]
52pub struct Declared;
53
54/// Assertions finalized — ready to solve.
55#[derive(Debug)]
56pub struct Asserted;
57
58/// Satisfiable — a model exists.
59/// Terminal phase.
60#[derive(Debug)]
61pub struct Sat;
62
63/// Unsatisfiable — no model exists.
64/// Terminal phase.
65#[derive(Debug)]
66pub struct Unsat;
67
68/// Solver budget exhausted without conclusive result.
69/// Terminal phase.
70#[derive(Debug)]
71pub struct Unknown;
72
73// ============================================================================
74// Sealed + Phase impls
75// ============================================================================
76
77macro_rules! impl_phase {
78    ($ty:ty, $name:literal) => {
79        #[allow(private_interfaces)]
80        impl sealed::Sealed for $ty {
81            fn _sealed() -> sealed::SealToken {
82                sealed::SealToken
83            }
84        }
85        impl Phase for $ty {
86            const NAME: &'static str = $name;
87        }
88    };
89}
90
91impl_phase!(Init, "init");
92impl_phase!(Declared, "declared");
93impl_phase!(Asserted, "asserted");
94impl_phase!(Sat, "sat");
95impl_phase!(Unsat, "unsat");
96impl_phase!(Unknown, "unknown");