Skip to main content

warp_types_pdr/
phase.rs

1//! PDR phase markers.
2//!
3//! Zero-sized types encoding the IC3/PDR workflow. Sealed —
4//! external crates cannot forge phases or create invalid transitions.
5//!
6//! # Phase machine
7//!
8//! ```text
9//!   Init
10//!     → build_model()       → Modeled
11//!   Modeled
12//!     → check()             → PdrResult
13//!       → Safe                terminal: inductive invariant found
14//!       → CounterexampleFound terminal: concrete trace to bad state
15//!       → Exhausted           terminal: frame budget exceeded
16//! ```
17
18// ============================================================================
19// Sealed trait
20// ============================================================================
21
22pub(crate) mod sealed {
23    pub(crate) struct SealToken;
24
25    #[allow(private_interfaces)]
26    pub trait Sealed {
27        #[doc(hidden)]
28        fn _sealed() -> SealToken;
29    }
30}
31
32// ============================================================================
33// Phase trait + markers
34// ============================================================================
35
36/// Marker trait for PDR phases. Sealed.
37pub trait Phase: sealed::Sealed + 'static {
38    /// Human-readable phase name.
39    const NAME: &'static str;
40}
41
42/// Initial state — no model loaded yet.
43#[derive(Debug)]
44pub struct Init;
45
46/// Model built — transition system loaded, ready for PDR.
47#[derive(Debug)]
48pub struct Modeled;
49
50/// Inductive invariant found — property is safe at all depths.
51/// Terminal phase.
52#[derive(Debug)]
53pub struct Safe;
54
55/// Counterexample trace found — property is violated.
56/// Terminal phase.
57#[derive(Debug)]
58pub struct CounterexampleFound;
59
60/// Frame budget exhausted without conclusive result.
61/// Terminal phase.
62#[derive(Debug)]
63pub struct Exhausted;
64
65// ============================================================================
66// Sealed + Phase impls
67// ============================================================================
68
69macro_rules! impl_phase {
70    ($ty:ty, $name:literal) => {
71        #[allow(private_interfaces)]
72        impl sealed::Sealed for $ty {
73            fn _sealed() -> sealed::SealToken {
74                sealed::SealToken
75            }
76        }
77        impl Phase for $ty {
78            const NAME: &'static str = $name;
79        }
80    };
81}
82
83impl_phase!(Init, "init");
84impl_phase!(Modeled, "modeled");
85impl_phase!(Safe, "safe");
86impl_phase!(CounterexampleFound, "counterexample-found");
87impl_phase!(Exhausted, "exhausted");