diff --git a/inference/src/fixpoint.rs b/inference/src/fixpoint.rs index 09441d1e..1691425b 100644 --- a/inference/src/fixpoint.rs +++ b/inference/src/fixpoint.rs @@ -51,12 +51,17 @@ fn invariant_cover( (covered, proof.invariants.len()) } +/// An inductive fixpoint pub struct FoundFixpoint { + /// The fixpoint term (the conjunction of these lemmas) pub proof: Vec, + /// Whether the discovered fixpoint implies the safety predicates pub safe: bool, + /// Total time for fixpoint calculation pub time_taken: Duration, - // How much of fixpoint covers handwritten invariant + /// Number of terms of handwritten invariant covered pub covered_handwritten: usize, + /// Total number of terms in the handwritten invariant pub size_handwritten: usize, } diff --git a/inference/src/hashmap.rs b/inference/src/hashmap.rs index 497b590e..d79baed2 100644 --- a/inference/src/hashmap.rs +++ b/inference/src/hashmap.rs @@ -1,15 +1,20 @@ // Copyright 2022-2023 VMware, Inc. // SPDX-License-Identifier: BSD-2-Clause +//! Aliases for HashMap and HashSet with deterministic iteration order. + use fxhash::FxBuildHasher; use std::hash::Hash; +/// HashMap with deterministic iteration order pub type HashMap = indexmap::IndexMap; +/// HashSet with deterministic iteration order pub type HashSet = indexmap::IndexSet; // pub type HashMap = std::collections::HashMap; // pub type HashSet = std::collections::HashSet; +/// Construct a deterministic HashSet from a `std::collections::HashSet`. pub fn set_from_std(s: std::collections::HashSet) -> HashSet { s.into_iter().collect() } diff --git a/inference/src/lib.rs b/inference/src/lib.rs index 0acacf22..1681cca0 100644 --- a/inference/src/lib.rs +++ b/inference/src/lib.rs @@ -6,13 +6,13 @@ //! Mostly consists of an implementation of the "q-alpha" algorithm, but also //! provides an implementation of Houdini. +#![allow(missing_docs)] // TODO: remove // configure clippy #![allow(clippy::needless_return)] #![allow(clippy::large_enum_variant)] #![allow(clippy::upper_case_acronyms)] #![allow(clippy::type_complexity)] // documentation-related lints (only checked when running rustdoc) -// #![warn(missing_docs)] #![allow(rustdoc::private_intra_doc_links)] #![deny(rustdoc::broken_intra_doc_links)] diff --git a/inference/src/updr.rs b/inference/src/updr.rs index 8c6643e9..5ba4f6ac 100644 --- a/inference/src/updr.rs +++ b/inference/src/updr.rs @@ -1,6 +1,8 @@ // Copyright 2022-2023 VMware, Inc. // SPDX-License-Identifier: BSD-2-Clause +//! Implementation of UPDR. See https://www.tau.ac.il/~sharonshoham/papers/jacm17.pdf. + use im::{hashset, HashSet}; use itertools::Itertools; use std::sync::Arc; @@ -12,31 +14,33 @@ use fly::term::cnf::term_to_cnf_clauses; use solver::conf::SolverConf; #[derive(Debug, Clone)] -pub struct Frame { +struct Frame { terms: Vec, } impl Frame { - pub fn strengthen(&mut self, term: Term) { + fn strengthen(&mut self, term: Term) { self.terms.push(term); } } -pub struct BackwardsReachableState { - pub id: usize, - pub term_or_model: TermOrModel, - pub num_steps_to_bad: usize, - pub known_absent_until_frame: usize, +struct BackwardsReachableState { + id: usize, + term_or_model: TermOrModel, + num_steps_to_bad: usize, + known_absent_until_frame: usize, } +/// State for a UPDR invariant search pub struct Updr { - pub solver_conf: Arc, + solver_conf: Arc, frames: Vec, backwards_reachable_states: Vec, currently_blocking_id: Option, } impl Updr { + /// Initialize a UPDR search pub fn new(solver_conf: Arc) -> Updr { Updr { solver_conf, @@ -46,7 +50,7 @@ impl Updr { } } - pub fn find_state_to_block(&mut self, module: &FOModule) -> Option { + fn find_state_to_block(&mut self, module: &FOModule) -> Option { // println!("start"); loop { // println!("loop"); @@ -323,7 +327,7 @@ impl Updr { out } - pub fn search(&mut self, m: &Module) -> Option { + fn find_frame(&mut self, m: &Module) -> Option { let module = FOModule::new(m, false, false, false); self.backwards_reachable_states = Vec::new(); for safety in &module.safeties { @@ -374,6 +378,12 @@ impl Updr { } } + /// Search for an inductive invariant. + pub fn search(&mut self, m: &Module) -> Option { + // TODO: is the and of the terms correct? + self.find_frame(m).map(|t| Term::and(t.terms)) + } + fn simplify(&mut self, module: &FOModule) { for frame in self.frames.iter_mut() { let mut terms: Vec = vec![]; diff --git a/temporal-verifier/src/command.rs b/temporal-verifier/src/command.rs index f8c367df..d07aa9cd 100644 --- a/temporal-verifier/src/command.rs +++ b/temporal-verifier/src/command.rs @@ -1,6 +1,8 @@ // Copyright 2022-2023 VMware, Inc. // SPDX-License-Identifier: BSD-2-Clause +//! The temporal-verifier binary's command-line interface. + use codespan_reporting::diagnostic::{Diagnostic, Label}; use path_slash::PathExt; use std::collections::HashMap; diff --git a/temporal-verifier/src/lib.rs b/temporal-verifier/src/lib.rs index 3ead1cbe..d111709b 100644 --- a/temporal-verifier/src/lib.rs +++ b/temporal-verifier/src/lib.rs @@ -6,13 +6,13 @@ //! The API is currently primarily available for testing purposes and not really //! intended as a general-purpose library. +#![deny(missing_docs)] // configure clippy #![allow(clippy::needless_return)] #![allow(clippy::large_enum_variant)] #![allow(clippy::upper_case_acronyms)] #![allow(clippy::type_complexity)] // documentation-related lints (only checked when running rustdoc) -// #![warn(missing_docs)] #![allow(rustdoc::private_intra_doc_links)] #![deny(rustdoc::broken_intra_doc_links)]