Advanced Features in Region Decomposition
Composition Operators
The [@@decomp ...] syntax allows chaining operations using operators defined in the Decomp module to build more complex analysis pipelines:
-
m |>> f(Apply Refiner): Takes the result of a decompositionm(e.g., fromtop ()) and applies a refiner functionfto it. This is the main way to chain steps like pruning or enumeration.let f' = f [@@decomp top () |>> prune] -
m << d1(Merge): Merges the decompositiond1intom. This effectively substitutes the definition of the function decomposed ind1wherever it appears in the regions ofm, re-calculating regions accordingly.(* Concept: Decompose g, then merge f's definition into it *) let d_g_merged_f = g [@@decomp top ~basis:[ [%id f] ] () << top () [%id f ]] -
m <|< d1(Compound Merge): A specialized merge that combines merging (<<) and combining (~|, see below) but preserves certain region distinctions fromm.let d_g_compound_f = g [@@decomp top ~basis:[ [%id f] ] () <|< top () [%id f ]] -
~| m(Combine): Takes a decompositionmand merges regions that have the exact same invariant, creating a disjunction (OR) of their constraints.let d_g_combined = ... [@@decomp ~| (top ~basis:[ [%id f] ] ())]
Key Refiners (Used with |>>)
These functions from the Decomp module modify an existing decomposition:
-
prune: Attempts to identify and remove infeasible regions (those whose constraints are unsatisfiable).let h a = ... let d_h_pruned = h [@@decomp top () |>> prune ] -
enumerate/enumerate_all: Refiners used for specific enumeration tasks, potentially related to generating test data satisfying region constraints.enumerate_alltakes a list of decompositions and a style (AdditiveorMultiplicative).let en' = en [@@decomp top () |>> enumerate_all ~style:Additive [ ... ]] let en'' = en [@@decomp top () |>> enumerate_all ~style:Multiplicative [ ... ]] -
merge_/compound_merge_: The underlying refiners used by the<<and<|<operators respectively.
Rule Specifications (~rule_specs)
You can provide background axioms or lemmas (marked [@@imandra_rule_spec]) via the ~rule_specs argument to top. These rules are applied during decomposition for:
- Rewriting: Simplifying terms within constraints or invariants.
- Forward Chaining: Adding derived facts to a region's context, potentially aiding feasibility checking or further simplification.
let map_recons len f x = ... [@@rw] [@@imandra_rule_spec]
let map_cons_eval f x y = ... [@@rw] [@@imandra_rule_spec]
let d_tgt''_rs = tgt''
[@@decomp top ~assuming:[%id asm'']
~rule_specs:[ [%id map_recons]; [%id map_cons_eval] ] ()]