; a buggy attempt on synthesis
(declare-datatypes () ((TriangleType EQUILATERAL ISOSCELES ACUTE OBTUSE RIGHT ILLEGAL)))
; Define the elementary holes. The assertions, which restrict the ranges
; of holes are optional. They are needed to eliminate identical solutions
; (eg, h1=1 and h1=-1 denote the same solution) but they may also make the solver
; more efficient.
(declare-const h0 Int)(assert (and (<= 0 h0)(< h0 2)))
(declare-const h1 Int)(assert (and (<= 0 h1)(< h1 7)))
(declare-const h2 Int)(assert (and (<= 0 h2)(< h2 3)))
(declare-const h3 Int)(assert (and (<= 0 h3)(< h3 3)))
(declare-const h4 Int)(assert (and (<= 0 h4)(< h4 7)))
(declare-const h5 Int)(assert (and (<= 0 h5)(< h5 3)))
(declare-const h6 Int)(assert (and (<= 0 h6)(< h6 3)))
(define-fun synth-var ((h Int)(a Int)(b Int)(c Int)) Int
(if (= h 0)
a
(if (= h 1)
b
c)))
(define-fun synth-connective ((h Int)(v1 Bool)(v2 Bool)) Bool
(if (= h 0)
(and v1 v2)
(or v1 v2)))
(define-fun synth-comparator ((h Int)(v1 Int)(v2 Int)) Bool
(if (= h 0)
(= v1 v2)
(if (= h 1)
(<= v1 v2)
(if (= h 2)
(< v1 v2)
(if (= h 3)
(>= v1 v2)
(if (= h 4)
(> v1 v2)
(if (= h 5)
true
false)))))))
; Now we can define the hole that will be synthesized.
; Technically, the hole is a grammar and the synthesizer
; finds a derivation. The derivation is identified by the
; values of h0, ..., h6.
(define-fun hole((a Int)(b Int)(c Int)) Bool
(synth-connective h0
(synth-comparator h1
(synth-var h2 a b c)
(synth-var h3 a b c))
(synth-comparator h4
(synth-var h5 a b c)
(synth-var h6 a b c))))
(define-fun classify ((a Int)(b Int)(c Int)) TriangleType
(if (and (>= a b) (>= b c))
(if (hole a b c)
(if (and (= a b) (= a c))
EQUILATERAL
ISOSCELES)
(if (not (= (* a a) (+ (* b b) (* c c))))
(if (< (* a a) (+ (* b b) (* c c)))
ACUTE
OBTUSE)
RIGHT))
ILLEGAL))
; Our spec is a set of eight test cases.
(assert (= (classify 2 12 27) ILLEGAL))
(assert (= (classify 5 4 3) RIGHT))
(assert (= (classify 26 14 14) ISOSCELES))
(assert (= (classify 19 19 19) EQUILATERAL))
(assert (= (classify 9 6 4) OBTUSE))
(assert (= (classify 24 23 21) ACUTE))
(assert (= (classify 7 5 6) ILLEGAL))
(assert (= (classify 26 26 7) ISOSCELES))
; Uncomment these asserts to force the synthesizer to produce alternative solutions.
; Once all four assertions are turned on, no more solutions remain.
;(assert (not (and (= h0 1)(= h1 0)(= h2 0)(= h3 1)(= h4 0)(= h5 1)(= h6 2)))) ; (or ( = a b)( = b c))
;(assert (not (and (= h0 1)(= h1 0)(= h2 0)(= h3 1)(= h4 1)(= h5 1)(= h6 2)))) ; (or ( = a b)(<= b c))
;(assert (not (and (= h0 1)(= h1 1)(= h2 0)(= h3 1)(= h4 1)(= h5 1)(= h6 2)))) ; (or (<= a b)(<= b c))
;(assert (not (and (= h0 1)(= h1 1)(= h2 0)(= h3 1)(= h4 0)(= h5 1)(= h6 2)))) ; (or (<= a b)( = b c))
; Here we suppress equivalent expressions by insisting on lexicograohic ordering of variables.
; These assertions, known in model checking as "symmetry reduction", are useful both to reduce the
; search space and to suppress enumeration of equivalent solutions to holes.
; i) enfore lexicographic ordering on h2, h3, and on h5, h6
(assert (and (< h2 h3)(< h5 h6))) ; example a=b is legal but b=a is not
; ii) lexicographic ordering on h2, h5
(assert (<= h2 h5)) ; ensures that only one of these is a valid solution: (or ( = a b)( = b c)), (or ( = b c)( = a b))
(check-sat)
(get-model)