This week we are transitioning to SMT solvers. SMT stands for satisfiablity modulo theory. The solver we'll use today (Rosette) is built on Racket.
(define-symbolic p boolean?)
(define-symbolic q boolean?)
(solve(assert(or p q)))
And we get p as #f and q as #t, which we know would satistfy p or q.
Can we make this model give us a different result?
(solve (assert(or p q)
(assert(or p (not q))))
(solve (assert(or p q))
(assert(or p (not q)))
(assert(or (not p) q))))
Q: this seems really cumbersome
A; you're not wrong. but we're going to build on this and it'll get better
(define-symbolic a integer?)
(define-symbolic b integer?)
(define-symbolic f (-> integer? integer?))
(solve (assert (> b a))
(assert (< (f b) (f a))))
(solve (assert (> b a))
(assert (< (f b) (f a)))
(assert (> a 20)))
It's taking a really long time... What might that happen? We have a really big search space and it's taking a long time to go through the whole thing.
How about some debugging? Let's try 10.
(solve (assert (> b a))
(assert (< (f b) (f a)))
(assert (> a 10)))
It works! By why? Tim said that these were real integers but they're not really. They are Alloy style integers.
We can fix this by setting bitwidth to false.
(current-bitwidth #f)
Once we do that we can run the version with 20 no problem.
(define-symbolic x integer?)
(define-symbolic root1 integer?)
(define-symbolic root2 integer?)
(solve (assert (forall(x integer?)(= (* (+ x root1) (+ x root2)) (+(* x x) (* x -198) -39483)))))