diff --git a/src/ast/rewriter/finite_set_axioms.h b/src/ast/rewriter/finite_set_axioms.h index 515e2a7fd..6b63a29f9 100644 --- a/src/ast/rewriter/finite_set_axioms.h +++ b/src/ast/rewriter/finite_set_axioms.h @@ -6,29 +6,9 @@ Module Name: finite_set_axioms.h Abstract: - Axiom schemas for finite sets. - Axiom schemars for finite sets are instantiated based on the state of the - congruence closure and existing assertions in for finite sets. This module implements axiom schemas that are invoked by saturating constraints with respect to the semantics of set operations. - - Let v1 ~ v2 mean that v1 and v2 are congruent - - The set-based decision procedure relies on saturating with respect - to rules of the form: - - x in v1 == v2, v1 ~ set.empty - -------------------------------- - not (x in set.empty) - - - x in v1 == v2, v1 ~ v3, v3 == (set.union v4 v5) - ----------------------------------------------- - x in v1 <=> x in v4 or x in v5 - - set.size : (FiniteSet S) -> Int - set.subset : (FiniteSet S) (FiniteSet S) -> Bool --*/ diff --git a/src/smt/theory_finite_set.h b/src/smt/theory_finite_set.h new file mode 100644 index 000000000..982876a33 --- /dev/null +++ b/src/smt/theory_finite_set.h @@ -0,0 +1,76 @@ +/*++ +Copyright (c) 2025 Microsoft Corporation + +Module Name: + + theory_finite_set.h + +Abstract: + + The theory solver relies on instantiating axiom schemas for finite sets. + The instantation rules can be represented as implementing inference rules + that encode the semantics of set operations. + It reduces satisfiability into a combination of satisfiability of arithmetic and uninterpreted functions. + + This module implements axiom schemas that are invoked by saturating constraints + with respect to the semantics of set operations. + + Let v1 ~ v2 mean that v1 and v2 are congruent + + The set-based decision procedure relies on saturating with respect + to rules of the form: + + x in v1 == v2, v1 ~ set.empty + ----------------------------------- + v1 = set.empty => not (x in v1) + + + x in v1 == v2, v1 ~ v3, v3 == (set.union v4 v5) + ----------------------------------------------- + x in v3 <=> x in v4 or x in v5 + + x in v1 == v2, v1 ~ v3, v3 == (set.intersect v4 v5) + --------------------------------------------------- + x in v3 <=> x in v4 and x in v5 + + x in v1 == v2, v1 ~ v3, v3 == (set.difference v4 v5) + --------------------------------------------------- + x in v3 <=> x in v4 and not (x in v5) + + x in v1 == v2, v1 ~ v3, v3 == (set.singleton v4) + ----------------------------------------------- + x in v3 <=> x == v4 + + x in v1 == v2, v1 ~ v3, v3 == (set.range lo hi) + ----------------------------------------------- + x in v3 <=> (lo <= x <= hi) + + x in v1 == v2, v1 ~ v3, v3 == (set.map f v4) + ----------------------------------------------- + x in v3 <=> set.map_inverse(f, x, v4) in v4 + + x in v1 == v2, v1 ~ v3, v3 == (set.map f v4) + ----------------------------------------------- + x in v4 => f(x) in v3 + + x in v1 == v2, v1 ~ v3, v3 == (set.select p v4) + ----------------------------------------------- + x in v3 <=> p(x) and x in v4 + +The central claim is that the above rules are sufficient to +decide satisfiability of finite set constraints. +Model construction proceeds by selecting every set.in(x_i, v) for a +congruence root v. Then the set of elements { x_i | set.in(x_i, v) } +is the interpretation. + +This approach, however, does not work with ranges, or is impractical. +For ranges, we are going to extract an interpretation for set variable v +directly from a set of range expressions. +Inductively, the interpretation of a range expression is given by the +range itself. It proceeds by taking unions, intersections and differences of range +interpretations. + +For Boolean lattice constraints given by equality, subset, strict subset and union, intersections, +the theory solver uses a stand-alone satisfiability checker for Boolean algebras to close branches. + +--*/