Balancing Versus Structured Decision Procedures: Antitrust ...
Programming with Decision Procedures
-
Upload
lillian-schroeder -
Category
Documents
-
view
30 -
download
1
description
Transcript of Programming with Decision Procedures
![Page 1: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/1.jpg)
Programming with Decision Procedures
Philippe SuterÉcole Polytechnique Fédérale de Lausanne, Switzerland
![Page 2: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/2.jpg)
What’s a Decision Procedure?
• 30’000 ft view, known uses
![Page 3: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/3.jpg)
This Talk
• High-level plan; from decision procedures to applications.
![Page 4: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/4.jpg)
Verification of functional programs
proof
counterexample(input, trace)
![Page 5: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/5.jpg)
sealed abstract class Treecase class Node(left: Tree, value: Int, right: Tree) extends Treecase class Leaf() extends Tree
object BST { def add(tree: Tree, element: Int): Tree = tree match { case Leaf() Node(Leaf(), element, Leaf())⇒ case Node(l, v, r) if v > element Node(add(l, element), v, r)⇒ case Node(l, v, r) if v < element Node(l, v, add(r, element))⇒ case Node(l, v, r) if v == element tree⇒ } ensuring (result ≠ Leaf())}
(tree = Node(l, v, r) v > element result ≠ Leaf())∧ ∧ ⇒ Node(result, v, r) ≠ Leaf()
We know how to generate verification conditions for functional programs
![Page 6: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/6.jpg)
Proving verification conditions
(tree = Node(l, v, r) v > element result ≠ ∧ ∧Leaf()) ⇒ Node(result, v, r) ≠ Leaf()
D.C. Oppen, Reasoning about Recursively Defined Data Structures, POPL ’78
G. Nelson, D.C. Oppen, Simplification by Cooperating Decision Procedure, TOPLAS ’79
Previous work gives decision procedures that can handle certain verification conditions
![Page 7: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/7.jpg)
sealed abstract class Treecase class Node(left: Tree, value: Int, right: Tree) extends Treecase class Leaf() extends Tree
object BST { def add(tree: Tree, element: Int): Tree = tree match { case Leaf() Node(Leaf(), element, Leaf())⇒ case Node(l, v, r) if v > element Node(add(l, element), v, r)⇒ case Node(l, v, r) if v < element Node(l, v, add(r, element))⇒ case Node(l, v, r) if v == element tree⇒ } ensuring (content(result) == content(tree) { element })∪
def content(tree: Tree) : Set[Int] = tree match { case Leaf() ⇒∅ case Node(l, v, r) content(l) { v } content(r)⇒ ∪ ∪ }}
![Page 8: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/8.jpg)
Complex verification conditionSet Expressions
Recursive FunctionAlgebraic Data Types
t1 = Node(t2, e1, t3) ∧ content(t4) = content(t2) { e∪ 2 } ∧ content(Node(t4, e1, t3)) ≠ content(t1) { e∪ 2 }where def content(tree: Tree) : Set[Int] = tree match { case Leaf() ⇒∅ case Node(l, v, r) content(l) { v } content(r)⇒ ∪ ∪}
?
![Page 9: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/9.jpg)
Our contribution
Decision procedures for extensions of algebraic data types with certain recursive functions
![Page 10: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/10.jpg)
Formulas we aim to proveQuantifier-free Formula
Generalized Fold Function
where def content(tree: Tree) : Set[Int] = tree match { case Leaf() ⇒∅ case Node(l, v, r) content(l) { v } content(r)⇒ ∪ ∪}
t1 = Node(t2, e1, t3) ∧ content(t4) = content(t2) { e∪ 2 } ∧ content(Node(t4, e1, t3)) ≠ content(t1) { e∪ 2 }
Domain with a Decidable Theory
![Page 11: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/11.jpg)
def α(tree: Tree) : C = tree match { case Leaf() ⇒ empty case Node(l, v, r) ⇒ combine(α(l), v, α(r))}
General form of our recursive functions
def content(tree: Tree) : Set[Int] = tree match { case Leaf() ⇒∅ case Node(l, v, r) content(l) { v } content(r)⇒ ∪ ∪}
empty : Ccombine : (C, E, C) → C
![Page 12: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/12.jpg)
How do we prove such formulas?Quantifier-free Formula
Generalized Fold Function
where def content(tree: Tree) : Set[Int] = tree match { case Leaf() ⇒∅ case Node(l, v, r) content(l) { v } content(r)⇒ ∪ ∪}
t1 = Node(t2, e1, t3) ∧ content(t4) = content(t2) { e∪ 2 } ∧ content(Node(t4, e1, t3)) ≠ content(t1) { e∪ 2 }
Domain with a Decidable Theory
![Page 13: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/13.jpg)
Separate the Conjuncts
c1 = content(t1) … c∧ ∧ 5 = content(t5)
t1 = Node(t2, e1, t3) t∧ 5 = Node(t4, e1, t3) ∧c4 = c2 { e∪ 2 } c∧ 5 ≠ c1 { e∪ 2 } ∧
t1 = Node(t2, e1, t3) ∧ content(t4) = content(t2) { e∪ 2 } ∧ content(Node(t4, e1, t3)) ≠ content(t1) { e∪ 2 }
![Page 14: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/14.jpg)
1
4
2 t2
t3
t1
1
7
0
t5
t4=4
2 t2
t3
t4
c2
c3
∪∪
∅
4
2c4 =
c4 = { 4 } { 2 } c∪ ∪∅∪ 3 c∪ 2
content=
t1 7
0
t5
=
![Page 15: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/15.jpg)
Overview of the decision procedure
c4 = c2 { e∪ 2 } c∧ 5 ≠ c1 { e∪ 2 }t1 = Node(t2, e1, t3)t5 = Node(t4, e1, t3) ∧
The resulting formula is in the decidable theory of sets
c1 = c2 { e∪ 1 } c∪ 3
c5 = c4 { e∪ 1 } c∪ 3∧
additional derived constraints
set constraints from the input formula
c4 = c2 { e∪ 2 }c5 ≠ c1 { e∪ 2 }c1 = c2 { e∪ 1 } c∪ 3
c5 = c4 { e∪ 1 } c∪ 3
∧∧∧
resulting formula
ci = content(ti), i { 1, …, ∈5 }
tree constraints from the input formula
mappings from the input formula
Decision Procedure for Sets
![Page 16: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/16.jpg)
What we have seen is a simple correct algorithm
But is it complete?
![Page 17: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/17.jpg)
A verifier based on such procedure
val c1 = content(t1) val c2 = content(t2)if (t1 ≠ t2) { if (c1 == ) {∅ assert(c2 ≠ )∅ x = c2.chooseElement }}
c1 = content(t1) c∧ 2 = content(t2) t∧ 1 ≠ t2 c∧ 1 = c∅∧ 2 = ∅
Warning: possible assertion violation
![Page 18: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/18.jpg)
…
Source of incompleteness
c1 = c∅∧ 2 = ∅ !
Models for the formula in the logic of sets must not contradict the disequalities over trees
c1 = content(t1) c∧ 2 = content(t2) t∧ 1 ≠ t2 c∧ 1 = c∅∧ 2 = ∅
t1 ≠ t2
∅
![Page 19: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/19.jpg)
How to make the algorithm complete
• Case analysis for each tree variable:– is it Leaf ?– Is it not Leaf ?
c1 = content(t1) c∧ 2 = content(t2) t∧ 1 ≠ t2 c∧ 1 = c∅∧ 2 = ∅
This gives a complete decision procedure for the content function that maps to sets
∧ t1 = Leaf t∧ 2 = Node(t3, e, t4) ∧ t1 = Leaf t∧ 2 = Leaf ∧ t1 = Node(t3, e1, t4) t∧ 2 = Node(t5, e2, t6) ∧ t1 Node(t3, e, t4) t∧ 2 = Leaf
![Page 20: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/20.jpg)
What about other content functions?
Tree content abstraction, as a:Set
Multiset
List
Tree size, height, min
Invariants (sortedness,…)
![Page 21: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/21.jpg)
Sufficient Surjectivity
How and when we can havea complete algorithm
![Page 22: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/22.jpg)
Decision Procedure for Sets
Choice of trees is constrained by sets
c4 = c2 { e∪ 2 } c∧ 5 ≠ c1 { e∪ 2 }t1 = Node(t2, e1, t3)t5 = Node(t4, e1, t3) ∧
c1 = c2 { e∪ 1 } c∪ 3
c5 = c4 { e∪ 1 } c∪ 3∧
c4 = c2 { e∪ 2 }c5 ≠ c1 { e∪ 2 }c1 = c2 { e∪ 1 } c∪ 3
c5 = c4 { e∪ 1 } c∪ 3
∧∧∧
additional derived constraints
set constraints from the input formula
resulting formula
ci = content(ti), i { 1, …, ∈5 }
tree constraints from the input formula
mappings from the input formula
![Page 23: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/23.jpg)
Inverse images
• When we have a model for c1, c2, … how can we pick distinct values for t1, t2,… ?
α
α-1
The cardinality of α-1 (ci) is what matters.
ci = content(ti)ti content∈ -1 (ci) ⇔
![Page 24: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/24.jpg)
‘Surjectivity’ of set abstraction
{ 1, 5 } 5
1
1
5
5
5 1
1…
∅ content-1
content-1
|content-1( )| = 1∅|content-1({1, 5})| = ∞
![Page 25: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/25.jpg)
In-order traversal
2
1 7
4
[ 1, 2, 4, 7 ]inorder-
![Page 26: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/26.jpg)
‘Surjectivity’ of in-order traversal
[ 1, 5 ] 5
1
1
5
[ ] inorder-1
inorder-1
|inorder-1(list)| =
(number of trees of size n = length(list))
![Page 27: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/27.jpg)
…
…
|inorder-1(list)|
length(list)
More trees map to longer lists
![Page 28: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/28.jpg)
An abstraction function α (e.g. content, inorder) is sufficiently surjective if and only if, for each number p > 0, there exist, computable as a function of p:
such that, for every term t, Mp(α(t)) or š(t) in Sp.
a finite set of shapes Sp
a closed formula Mp in the collection theory such that Mp(c) implies |α-1(c)| > p
--
Pick p sufficiently large.Guess which trees have a problematic shape.
Guess their shape and their elements.By construction values for all other trees can be found.
![Page 29: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/29.jpg)
For a conjunction of n disequalities over tree terms, if for each term we can pick a value from a set of trees of size at least n+1, then we can pick values that satisfy all disequalities.
We can make sure there will be sufficiently many trees to choose from.
Generalization of the Independence of Disequations Lemma
![Page 30: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/30.jpg)
Scope of our result - Examples
Tree content abstraction, as a:Set
Multiset
List
Tree size, height, min
Invariants (sortedness,…)
[Kuncak,Rinard’07]
[Piskac,Kuncak’08]
[Plandowski’04]
[Papadimitriou’81]
[Nelson,Oppen’79]
![Page 31: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/31.jpg)
def content(tree: Tree) : Set[Int] = tree match { case Leaf() Set.empty⇒ case Node(l, v, r) (content(l) ++ content(r)) + v⇒}
def allEven(list: List) : Boolean = list match { case Nil() ⇒ true case Cons(x, xs) (x % 2 == 0) && allEven(list)⇒}
def max(tree: Tree) : Option[Int]= tree match { case Leaf() None⇒ case Node(l, v, r) Some(max(l), max(r)) ⇒ match { case (None, None) Some(v)⇒ case (Some(lm), None) max(lm, v)⇒ case (None, Some(rm)) max(rm, v)⇒ case (Some(lm), Some(rm)) (max(lm, rm), v)⇒})}
…as well as any catamorphism
that maps to a finite domain!
![Page 32: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/32.jpg)
Sufficiently Surjectivity Holds in Practice
Theorem: For every sufficiently surjective abstraction our procedure is complete.
Theorem: The following abstractions are sufficiently surjective: set content, multiset content, list (any-order), tree height, tree size, minimum, sortedness
A complete decision procedure for all these cases!
![Page 33: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/33.jpg)
»«In the context of a project to reason about a
domain specific language called Guardol for XML message processing applications […the] procedure has allowed us to prove a number of interesting things […], so I'm extremely grateful for it.
Mike Whalen (University of Minnesota & Rockwell Collins)
Sufficiently Surjectivity Holds in Practice
K. Slind, D. Hardin, M. Whalen, T.H. Pham, The Guardol Language and Verification System, TACAS 2012[ ]
![Page 34: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/34.jpg)
• Reasoning about functional programs reduces to proving formulas
• Decision procedures always find a proof or a counterexample
• Previous decision procedures handle recursion-free formulas
• We introduced decision procedures for formulas with recursive fold functions
Decision Procedures for Recursive Abstractions Functions
![Page 35: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/35.jpg)
Leon(Online)
• A verifier for Scala programs.• The programming and specification languages
are the same purely functional subset.
def content(t: Tree) = t match { case Leaf ⇒ Set.empty case Node(l, v, r) ⇒ (content(l) ++ content(r)) + e}
def insert(e: Int, t: Tree) = t match { case Leaf ⇒ Node(Leaf, e, Leaf) case Node(l, v, r) if e < v ⇒ Node(insert(e, l), v, r) case Node(l, v, r) if e > v ⇒ Node(l, v, insert(e, r)) case _ t⇒} ensuring( res content(res) == content(t) + e)⇒
![Page 36: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/36.jpg)
Satisfiability ModuloRecursive Programs
…of quantifier-free formulas in a decidable base theory…
…pure, total, deterministic, first-order and terminating on all inputs…
![Page 37: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/37.jpg)
• Semi-decidable problem of great interest:– applications in verification, testing, theorem
proving, constraint logic programming, …• Our algorithm always finds counter-examples
when they exist, and will also find assume/guarantee style proofs.
• It is a decision procedure for infinitely and sufficiently surjective abstraction functions.
• We implemented it as a part of a verification system for a purely functional subset of Scala.
Satisfiability Modulo Recursive Programs
![Page 38: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/38.jpg)
Proving/Disproving Modulo Recursive Programs
![Page 39: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/39.jpg)
Proving by Inliningdef size(lst: List) = lst match { case Nil ⇒ 0 case Cons(_, _) ⇒ 1} ensuring(res ⇒ res ≥ 0)
(if(lst = Nil) 0 else 1) < 0
Convert pattern-matching,negate.
Unsatisfiable.
![Page 40: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/40.jpg)
Proving by Inliningdef size(lst: List) = lst match { case Nil ⇒ 0 case Cons(x, xs) ⇒ 1 + size(xs)} ensuring(res ⇒ res ≥ 0)
(if(lst = Nil) 0 else 1 + size(lst.tail)) < 0
Convert pattern-matching,negate,treat functions as uninterpreted.
Satisfiable.(e.g. for size(Nil) = -2)
Inline post-condition.
(if(lst = Nil) 0 else 1 + size(lst.tail)) < 0 ∧size(lst.tail) ≥ 0
Unsatisfiable.
![Page 41: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/41.jpg)
Disproving by Inliningdef size(lst: List) = lst match { case Nil ⇒ -1 case Cons(x, xs) ⇒ 1 + size(xs)}
size(lst) < 0
Negate,treat functions as uninterpreted.
Satisfiable.(e.g. lst = [0], size([0]) = -1)
def prop(lst: List) = { size(lst) ≥ 0} ensuring(res ⇒ res)
Inline definition of size(lst).
size(lst) < 0 ∧size(lst) = (if(lst = Nil) -1 else 1 + size(lst.tail))
Satisfiable.(e.g. lst = [0,1], size([1]) = -2)
size(lst) < 0 ∧size(lst) = (if(lst = Nil) -1 else 1 + size(lst.tail)) ∧size(lst.tail) = (if(lst.tail = Nil) -1 else 1 + size(lst.tail.tail))
Satisfiable.(e.g. lst = [0,1,2], …)
![Page 42: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/42.jpg)
Disproving with Inlining
size(lst)
?
There are always unknown branches in the evaluation tree.We can never be sure that there exists no smaller solution.
?
?
size(lst.tail)
size(lst.tail.tail)
…
![Page 43: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/43.jpg)
Branch Rewritingsize(lst) = if(lst = Nil) { -1} else { 1 + size(lst.tail)}
size(lst) = ite1
∧ p1 lst = Nil⇔ ∧ p1 ite⇒ 1 = -1 ∧ ¬p1 ite⇒ 1 = 1 + size(lst.tail)
size(lst)
p1 ¬p1
… ∧ p1
?
• Satisfiable assignments do not depend on unknown values.
• Unsatisfiable answers have two possible meanings.
![Page 44: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/44.jpg)
Algorithm(φ, B) = unroll(φ, _)while(true) {
solve(φ ∧ B) match { case “SAT” ⇒ return “SAT”
case “UNSAT” solve(⇒ φ) match { case “UNSAT” ⇒ return “UNSAT”
case “SAT” (⇒ φ, B) = unroll(φ, B) } }}
Inlines some postconditions and bodies of function applications that were guarded by a literal in B, returns the new formula and new set of guards B.
“I’m feeling lucky”
Some literals in B may be implied by φ : no need to unroll what they guard.
Inlining must be fair
![Page 45: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/45.jpg)
Completeness for Counter-Examples• Let a1,… an be the free variables of φ, and c1,…,cn
be a counter-example to φ.• Let T be the evaluation tree of φ[a1→c1, …, an→cn].
• Eventually, the algorithm will reach a point where T is covered.
?
?
?
?
T :
![Page 46: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/46.jpg)
Termination for Sufficiently Surjective Abstraction Functions
![Page 47: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/47.jpg)
Sufficiently Surjective Abstractions• The algorithm terminates, and is thus a
decision procedure for the case of infinitely and sufficiently surjective abstraction functions.
def α(tree: Tree) : C = tree match { case Leaf() ⇒ empty case Node(l, v, r) ⇒ combine(α(l), v, α(r))}
![Page 48: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/48.jpg)
A Tale of Two Techniques
φ ≡ … α(t) …
t ≡ t ≡
t ≡
t ≡
t ≡
∨ ψ(α(t))• For catamorphisms, unrolling α
corresponds to enumerating potential counter-examples by the size of their tree.
• When all required trees have been considered, a formula at least as strong as ψ(α(t)) is derived by the solver.
![Page 49: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/49.jpg)
Verification System
![Page 50: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/50.jpg)
(Some) Experimental ResultsBenchmark LoC #Funs. #VCs. Time (s)
ListOperations 107 15 27 0.76
AssociativeList 50 5 11 0.23
InsertionSort 99 6 15 0.42
RedBlackTrees 117 11 24 3.73
PropositionalLogic 86 9 23 2.36
AmortizedQueue 124 14 32 3.37
VSComp 94 11 23 0.79
677 71 155 11.66
Functional correctness properties of data structures: red-black trees implement a set and maintain height invariants, associative list has read-over-write property, insertion sort returns a sorted list of identical content, amortized queue implements a balanced queue, etc.
![Page 52: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/52.jpg)
• Semi-decidable problem of great interest:– applications in verification, testing, theorem
proving, constraint logic programming, …• Our algorithm always finds counter-examples
when they exist, and will also find assume/guarantee style proofs.
• It is a decision procedure for infinitely and sufficiently surjective abstraction functions.
• We implemented it as a part of a verification system for a purely functional subset of Scala.
Satisfiability Modulo Recursive Programs
![Page 53: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/53.jpg)
“The smallest positive integer that is a multiple
of both a and b.” “All binary search trees whose content is a
given set.”
“The choice of items that maximize total value given
a bound on weight.”
That’s easier said than done.« »
![Page 54: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/54.jpg)
• Long history of constraint solving languages
CLP(X) …
• Can we bring similar benefits to mainstream languages by building on existing tools?
That’s easier said than done.« »
![Page 55: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/55.jpg)
Pragmatic Constraint Programming
Programming by constraints is appropriate for some but not all tasks.• The performance of regular, imperative, code
should not be affected.• From the programmer’s point of view, changes
to the language should be minimal.Constraints should be a feature, not necessarily the foundation.
![Page 56: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/56.jpg)
• We present Kaplan, an extension of Scala with first-class constraints.
• Programmers can manipulate constraints like other values and combine them.
• Constraints can be solved eagerly, or lazily with logical variables.
• At run time, Kaplan invokes a constraint solver supporting user-defined recursive functions.
Constraints as Control
![Page 57: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/57.jpg)
Kaplan in Action
![Page 58: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/58.jpg)
Kaplan in Action
((x : Int) ⇒ x > 0).find> Some(1)
((x : Int) ⇒ x != x).find> None
val it = ((x : Int) ⇒ 4 < x).findAll> Non-empty iterator.
it.take(6).toList> List(5, 6, 7, 8, 10, 9)
![Page 59: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/59.jpg)
Kaplan in Action
val (a, b) = (12, 8)val (lcm, _, _) = ((m, fa, fb) ⇒ m > 0 && m == fa * a && m == fb * b) .minimizing((m,fa,fb) ⇒ m).find> Some(24)
((t : Tree) ⇒ isBST(t) && elems(t) == Set(1, 2, 3)) .findAll.toList> List(Node(Node(L, 1, L), 2, Node(L, 3, L)), Node(Node(Node(L, 1, L), 2, L), 3, L), Node(L, 1, Node(L, 2, Node(L, 3, L))))
![Page 60: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/60.jpg)
Language Integration
![Page 61: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/61.jpg)
class Constraint[T] extends Function[T,Boolean] { def find : Option[T]}
Potentially a tuple type. Scala representation of a first-class function.
All you Need is…
![Page 62: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/62.jpg)
Semantics is Intuitive
t1 | μ1 →S t2 | μ2
t1 | μ1 → t2 | μ2
Host
¬∃M . M ⊨ φ
(λxn . φ(xn)).find | μ → None | μS-Unsat
M ⊨ φ
(λxn . φ(xn)).find | μ → Some(M(xn))| μS-Sat
![Page 63: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/63.jpg)
Derived Constructs
• findAll creates an iterator that stores and negates values returned by find.
• minimizing runs a search by dichotomy.
• Constraints can be combined:((x : Int) ⇒ x > 0) && ((x : Int) ⇒ x < 10)
![Page 64: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/64.jpg)
A SAT Solver
def solve(problem : Seq[Seq[Int]]) : Option[Map[Int,Boolean]] = { problem.map(clause ⇒ clause.map(lit ⇒ ((m : Map[Int,Boolean]) ⇒ m(abs(lit)) == (lit > 0)).c ).reduceLeft(_ || _)).reduceLeft(_ && _).find}
Problem is given as a DIMACS-like list of clauses
Constraint for one literal
Constraint for one clause
Constraint for the conjunction
Result is an assignment, or None
![Page 65: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/65.jpg)
Embedding: Lifting Syntax Trees• We need access to the ASTs of constraints.• We rely on implicit type conversions.
• We check that the constraint falls in the supported fragment and extracts the AST.
implicit def lift[A](f : Function[A,Boolean]) : Constraint[A]
((x : Int) ⇒ x > 0).find
lift[Int](((x : Int) ⇒ x > 0)).find λ
>
$1 0
![Page 66: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/66.jpg)
Constraint Language and Solver
![Page 67: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/67.jpg)
Constraint Language: Primitive Types
• Booleans
• Integers
• Sets
• Maps
||, &&, !, ==, !=
+, -, *, /, >, <, ==, !=
s(x), ++, --, **, Set(…), subsetOf
m(x), m.isDefinedAt(x), ++, Map(x -> i)
![Page 68: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/68.jpg)
Constraint Language: Recursive Functions@spec def noneDivides(from : Int, j : Int) : Boolean = { if(from == j) { true } else { !divides(from, j) && noneDivides(from + 1, j) }}@spec def isPrime(i : Int) = (i >= 2 && noneDivides(2, i))
((x : Int) ⇒ isPrime(x)).find> Some(2)
((x : Int) ⇒ isPrime(x)).minimizing(x ⇒ x).findAll.take(10)> 2, 3, 5, 7, 11, 13, 17, 19, 23, 29
![Page 69: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/69.jpg)
Constraint Language: Data Types@spec sealed abstract class List@spec case class Cons(head : Int, tail : List) extends List@spec case class Nil() extends List
@spec def content(lst : List) = lst match { case Nil() ⇒ Set.empty case Cons(x, xs) ⇒ Set(x) ++ content(xs)}@spec def isSorted(lst : List) = ...
val s = Set(0, 1, -3)((l : List) ⇒ isSorted(lst) && content(lst) == s).solve
> Cons(-3, Cons(0, Cons(1, Nil())))
![Page 70: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/70.jpg)
Underlying Constraint Solver
![Page 71: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/71.jpg)
Applications and Conclusion
![Page 72: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/72.jpg)
Initial Experience• Solving puzzles• Enumerating data structures for testing• Executable specifications
– Can be used as method stubs…– …or substitute when a contract check fails
[Samimi et al. ECOOP 2010]
• Simplifies applications that depend on SMT solvers– counter-example guided inductive synthesis
• Ask us for a live demo!
![Page 73: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/73.jpg)
Related Work
• Prolog + CLP(X)
• Functional Logic Programming (Curry)
• Dminor [Bierman et al. ICFP 2010]
• Jeeves [Yang et al. POPL 2012]
• Complete Functional Synthesis [Kuncak et al. PLDI 2010]
![Page 74: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/74.jpg)
• We presented Kaplan, an extension of Scala with first-class constraints.
• Programmers can manipulate constraints like other values and combine them.
• Constraints can be solved eagerly, or lazily with logical variables.
• At run time, Kaplan invokes a constraint solver supporting user-defined recursive functions.
Constraints as Control
![Page 75: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/75.jpg)
The Compilation Approach
![Page 76: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/76.jpg)
Program synthesis
Program specification(implicit)
find y suchThat property(x, y)
Program implementation(explicit, programming language)
z1 = f1(x)z2 = f2(z1, x)y = f3(z1, z2, x)
The generated code is correct by construction
![Page 77: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/77.jpg)
Compilation Approach• Localized invocation of constraint solving.
• Replace, when possible, by explicit computation.
standard code
implicit code
Turn decision procedures into synthesis procedures
… val x = readInteger() + 4
val r = (y ⇒ 5*x+7*y == 31).solve
println(“r^2: “ + r*r)…
![Page 78: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/78.jpg)
Decision vs. synthesis proceduresFor a well-defined class of formulas:
Decision procedure
• Input: a formula
Synthesis procedure
• Input: a formula, with input and output variables
• Output: a modelof the formula
• Output: a program to compute output values from input values
5*x + 7*y = 31
x := 2y := 3
Inputs: { x } outputs: { y }5*x + 7*y = 31
y := (31 – 5*x) / 7
(model-generating)
a theorem prover that always succeeds a synthesizer that always succeeds
![Page 79: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/79.jpg)
def secondsToTime(totalSeconds: Int) : (Int, Int, Int) = ((h: Int, m: Int, s: Int) (⇒ h * 3600 + m * 60 + s == totalSeconds && h ≥ 0 && m ≥ 0 && m < 60 && s ≥ 0 && s < 60 )).solve
An example
def secondsToTime(totalSeconds: Int) : (Int, Int, Int) = val t1 = totalSeconds / 3600 val t2 = totalSeconds + ((-3600) * t1) val t3 = min(t2 / 60, 59) val t4 = totalSeconds + ((-3600) * t1) + (-60 * t3) (t1, t3, t4)
3787 seconds 1 hour, 3 mins. and 7 secs.
![Page 80: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/80.jpg)
• Synthesis: our procedures start from an implicit specification.
• Functional: computes a function that satisfies a given input/output relation.
• Complete: guaranteed to work for all specification expressions from a well-defined class.
Complete Functional Synthesis
![Page 81: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/81.jpg)
Starting point: quantifier elimination
• A call of the form
• Corresponds to constructively solving the quantifier elimination problem
where a is a parameter
r = (x F( a, x )).solve⇒
∃ x . F( a, x )
“let r be x such that F(a, x) holds”
![Page 82: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/82.jpg)
Quantifier elimination
• Converts a formula into an equivalent one with no quantified variables
Observation: we can obtain witness termsfor the eliminated variables
• Prominent application of Q.E.:integer linear arithmetic
• Witness terms become the instructions of the synthesized program
![Page 83: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/83.jpg)
val z = ceil(5*a/12)val x = -7*z + 3*aval y = 5*z + -2*a
((x, y) 5 * x + 7 * y == a && x ≤ y).solve⇒
z = ceil(5*31/12) = 13x = -7*13 + 3*31 = 2y = 5*13 – 2*31 = 3
∃ x y . 5x + 7y = a x ≤ y∃ ∧
x = 3ay = -2a
Use extended Euclid’s algorithm to find particular solution to 5x + 7y = a:
Express general solution of equations for x, y using a new variable z:
x = -7z + 3ay = 5z - 2a
Rewrite inequations x ≤ y in terms of z: 5a ≤ 12z z ≥ ceil(5a/12)
Obtain synthesized program:
For a = 31:
Corresponding quantifier elimination problem:
![Page 84: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/84.jpg)
((x, y) 5 * x + 7 * y == a && x ≤ y && x ≥ 0).solve⇒
Express general solution of equations for x, y using a new variable z:
x = -7z + 3ay = 5z - 2a
Rewrite inequations x ≤ y in terms of z: z ≥ ceil(5a/12)
assert(ceil(5*a/12) ≤ floor(3*a/7))val z = ceil(5*a/12)val x = -7*z + 3*aval y = 5*z + -2*a
Obtain synthesized program:
z ≤ floor(3a/7)Rewrite x ≥ 0:
ceil(5a/12) ≤ floor(3a/7)Precondition on a:(exact precondition)
![Page 85: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/85.jpg)
Applicability
• In principle, any model-generating decision procedure can be adapted; at the limit, the generated program is the decision procedure.
• Quantifier-elimination decision procedures:– Integer linear (Presburger) arithmetic– Polynomial real arithmetic– Algebraic data types (lists, trees, etc.)– Boolean algebra with Presburger arithmetic (BAPA)
![Page 86: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/86.jpg)
• We proposed a method to devise synthesis procedures from decision procedures.
• Our synthesis algorithms are guaranteed to find a solution when there exists one.
• Our techniques can be integrated into general purpose programming languages.
• We built a Scala compiler plugin integrating integer arithmetic and set synthesis into Scala.
Compilation Approach
![Page 87: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/87.jpg)
Programming with Decision Procedures
• Requires runtime solver.• Language of constraints
is extensible.• First-class constraints,
can be combined.• Can also enumerate
solutions.
• Efficient generated code.• Language of constraints
is syntactically fixed.• Constraints need to be
known at compile time.• Computes a single
solution.
Run time approach Compilation approach
• In both cases:– Constraints are built from existing constructs.– Semantics are intuitive.
![Page 88: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/88.jpg)
Summary Slide
• Same as first, perhaps with paper references.• a
![Page 89: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/89.jpg)
Thank you.
![Page 90: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/90.jpg)
Sets with Cardinality Constraints
• Decision procedure for constraints on sets with the cardinality operator.
• Based on decomposition techniques to scale.• Integrated into Z3, works in combination with all
other supported theories.• Part of verification system for functional
programs.P. Suter, R. Steiger, and V. Kuncak, Sets with Cardinality Constraints in Satisfiability Modulo Theories, VMCAI 2011[ ]
x A B A | B ∈ ∧ ⊆ ∧ ∩ C | ≤ 2
![Page 91: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/91.jpg)
Type Inference for PHP
• Uses abstract interpretation to estimate the set of possible types at all program points.
• Precise abstractions for arrays.• Can use code instrumentation to enhance the
precision of the analysis.
E. Kneuss, P. Suter, and V. Kuncak, Runtime Instrumentation for Precise Flow-Sensitive Type Analysis, RV 2010[ ]
“PHP Analyzer for Type Mismatch”
![Page 92: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/92.jpg)
Interprocedural Effect Analysis
“Interprocedural Static Analyzer for Effects”
with E. Kneuss and V. Kuncak, work in progress.[ ]
• Computes summaries of heap side-effects.• Handling of closures is challenging:
– Analyze “around” problematic calls.– Include callback invocations in effect summaries.
• Targets the whole Scala language.
![Page 93: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/93.jpg)
Thank you.
![Page 94: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/94.jpg)
Concrete Meets Logical• Logical and concrete variables are distinct, but
are inter-convertible.def max(x : L[Int], y : L[Int]) : L[Int] = { ((a : Int) ⇒ a >= x && a >= y && (a == x || a == y)).lazySolve}
> (max(3, 5)) : Int5
implicit def concretize[T](l : L[T]) : T = l.valueimplicit def lift[T](c : T) : L[T] = ...
• Nothing is logical by default; this preserves efficient execution.
![Page 95: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/95.jpg)
for Comprehensions
for((x,y) ← ((x: Int, y: Int) ⇒ x > 0 && y > x && x * 2 + y * 3 <= 40).findAll; if(isPrime(y)); z ← ((z: Int) ⇒ z * x == 3 * y * y).findAll) yield (x, y, z)
Can you find positive x, y, z such that 2x + 3y ≤ 40, xz = 3y2, and y is prime?
> (1,2,12), (1,3,27), (1,5,75), (1,7,147), (1,11,363), (3,11,121), (3,5,25), (3,7,49)
Returned expressionFilter: arbitrary boolean expression.
Generators: sequences, computed lazily
![Page 96: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/96.jpg)
Higher-Order Theorem Proving
• w/ N. Bjorner at MSR
![Page 97: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/97.jpg)
Related Work
G. Nelson, D.C. Oppen, Simplification by Cooperating Decision Procedure, TOPLAS ’79
V. Sofronie-Stokkermans, Locality Results for Certain Extensions of Theories with Bridging Functions, CADE ’09
Some implemented systems: ACL2, Isabelle, Coq, Verifun, Liquid Types
![Page 98: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/98.jpg)
Related Work• SMT Solvers + axioms
– can be very efficient for well-formed axioms– in general, no guarantee than instantiations are fair– cannot in general conclude satisfiability (changing…)
• Interactive verification systems (ACL2, Isabelle, Coq)
– very good at building inductive proofs– could benefit greatly from counter-example
generation (as feedback to the user but also to prune out branches in the search)
• Sinha’s Inertial Refinement technique– similar use of “blocked paths”– no guarantee to find counter-examples
![Page 99: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/99.jpg)
Related Work, continued• DSolve (aka. “Liquid Types”)
– because the proofs are based on type inference rules, cannot immediately be used to prove assertions relating different functions
• Bounded Model Checking– offer similar guarantees on the discovery of
counter-examples– reduces to SAT rather than SMT– unclear when it is complete for proofs
• Finite Model Finding (Alloy, Paradox)– lack of theory reasoning, no proofs
![Page 100: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/100.jpg)
Logical Variables
![Page 101: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/101.jpg)
class L[T] { def value : T}
class Constraint[T] extends Function[T,Boolean] { def find : Option[T] def lazyFind : Option[L[T]]}
Logical Variables
A constraint store is maintained at run time.
![Page 102: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/102.jpg)
Logical Variables
val x = ((x : Int) ⇒ x > 0).lazyFind.get> x : L[Int] = L(?)x.value> 1
val x = ((x : Int) ⇒ x > 0).lazyFind.getval y = ((y : Int) ⇒ 0 < y && y < x).lazyFind.get> y : L[Int] = L(?)x.value> 2y.value> 1 Constrains both x and y.
Ensures existence of x, does not commit to a value.
![Page 103: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/103.jpg)
Branching on Logical Conditions
val a = Console.readIntval x = ((x : Int) ⇒ true).lazyFind.getval y = ((y : Int) ⇒ a / x).lazyFind.get
assuming(a == x * y && x != 1 && x != a) { println(a + “ is composite”) println(x.value + “ * “ + y.value)} otherwise { println(a + “ is prime”)} x is arbitrary
In this branch, x and y are a decompositon of a.
“Biased if-then-else”
![Page 104: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/104.jpg)
Semantics with Constraint Store
t1 | μ1 →S t2 | μ2Hostt1 | ⟨ μ1, κ ⟩ → t2 | ⟨ μ2, κ ⟩t1 | ⟨ μ1, κ ⟩ → t2 | ⟨ μ2, κ ⟩
Constraint store: a formula over all logical variables.
![Page 105: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/105.jpg)
Semantics with Constraint Store
The variables are returned. The model
M is ignored.
Bound variables are mapped to fresh
variables in κ.
Enforces single value semantics.
The existence of M is guaranteed by the execution order.
L-SatM ⊨ κ ∧ φ[xn an↦ f] anf fresh in κ
(λxn . φ(xn,an)).lazyFind | ⟨ μ, κ → Some(an⟩ f)| ⟨ μ, κ ∧ φ[xn ↦anf] ⟩
L-Unsat¬∃M . M ⊨ κ ∧ φ[xn an↦ f] anf fresh in κ
(λxn . φ(xn,an)).lazyFind | ⟨ μ, κ → None | ⟩ ⟨ μ, κ ⟩
ValueM ⊨ κ
a.value | ⟨ μ, κ → ⟩ M(a)| ⟨ μ, κ a = ∧ M(a) ⟩
Liftc a constant af fresh in κ
c.lift | ⟨ μ, κ → a⟩ f| ⟨ μ, κ a∧ f = c ⟩
![Page 106: Programming with Decision Procedures](https://reader036.fdocuments.us/reader036/viewer/2022062721/568136df550346895d9e79df/html5/thumbnails/106.jpg)
Implementation of Constraint Store• For each logical variable, we maintain two
variables in the solver:- a value variable and- a guard variable
(y ⇒ x + y >= 4).lazySolve gx g∨ y v⇒ x + vy ≥ 4
• Guard denotes “liveness”. • Works as a garbage collection mechanism.• .value never triggers a new search, last result
is always cached.