add remaining logic ops; add sec4 tests; TODO: add hash and fix sol ops

This commit is contained in:
Stephen Chang 2016-09-02 23:03:55 -04:00
parent f22619f47b
commit 4007d64ff1
3 changed files with 261 additions and 8 deletions

View File

@ -11,6 +11,8 @@ Is concrete? broken?
Rosette TODO:
- fix documentation of synthesize
- #:forall accepts everything, not just constant?s
- doc typo: core
- Returns the unsatisfiable core stored in the given satisfiable solution
Rosette use case questions:
- does the predicate in define-symbolic need to be an arbitrary expression?

View File

@ -561,6 +561,7 @@
(provide (rosette-typed-out [printf : (Ccase-> (C→ CString CUnit)
(C→ CString Any CUnit)
(C→ CString Any Any CUnit))]
[displayln : (C→ Any CUnit)]
[error : (Ccase-> (C→ (CU CString CSymbol) Nothing)
(C→ CSymbol CString Nothing))]
[void : (C→ CUnit)]
@ -706,7 +707,9 @@
(C→ Num Num))]
[truncate : (Ccase-> (C→ CNum CNum)
(C→ Num Num))]
[sgn : (Ccase-> (C→ CInt CInt)
[sgn : (Ccase-> (C→ CZero CZero)
(C→ Zero Zero)
(C→ CInt CInt)
(C→ Int Int)
(C→ CNum CNum)
(C→ Num Num))]
@ -834,8 +837,7 @@
[bitvector->natural : (C→ BV Nat)]
[integer->bitvector : (C→ Int BVPred BV)]
[bitvector-size : (C→ CBVPred CPosInt)]
[bitvector-size : (C→ CBVPred CPosInt)]))
;; ---------------------------------
;; Uninterpreted functions
@ -848,9 +850,9 @@
;; ---------------------------------
;; Logic operators
[! : (C→ Bool Bool)]
[<=> : (C→ Bool Bool Bool)]))
(provide (rosette-typed-out [! : (C→ Bool Bool)]
[<=> : (C→ Bool Bool Bool)]
[=> : (C→ Bool Bool Bool)]))
(define-typed-syntax &&
[(_ e ...)
@ -914,14 +916,18 @@
(define-base-types CSolution CPict)
(provide (rosette-typed-out [core : (C→ Any Any)]
(provide (rosette-typed-out [core : (C→ CSolution (U (Listof Any) CFalse))]
; TODO: implement hash
[model : (C→ CSolution Any)]
[sat : (Ccase-> (C→ CSolution)
(C→ Any CSolution))]
[sat? : (C→ Any Bool)]
[unsat? : (C→ Any Bool)]
[unsat : (Ccase-> (C→ CSolution)
(C→ (CListof Bool) CSolution))]
[forall : (C→ (CListof Any) Bool Bool)]
[exists : (C→ (CListof Any) Bool Bool)]))
(define-typed-syntax verify
[(_ e)
[ [e e- : _]]

View File

@ -0,0 +1,245 @@
#lang s-exp "../../rosette/rosette2.rkt"
(require "../rackunit-typechecking.rkt"
"check-type+asserts.rkt")
;; Examples from the Rosette Guide, Section 4
;; 4.1 Equality
;; should equal? produce CBool?
;; (check-type (equal? 1 #t) : CBool -> #f)
;; (check-type (equal? 1 1.0) : CBool -> #t)
;; (check-type (equal? (list 1) (list 1.0)) : CBool -> #t)
;; (check-type (equal? (box 1) (box 1)) : CBool -> #t)
;; (check-type (equal? (box 1) (box 1.0)) : CBool -> #t)
;; (check-type (equal? (list (box 1)) (list (box 1))) : CBool -> #t)
;; (check-type (equal? (list (box 1)) (list (box 1.0))) : CBool -> #t)
(check-type (equal? 1 #t) : Bool -> #f)
(check-type (equal? 1 1.0) : Bool -> #t)
(check-type (equal? (list 1) (list 1.0)) : Bool -> #t)
(check-type (equal? (box 1) (box 1)) : Bool -> #t)
(check-type (equal? (box 1) (box 1.0)) : Bool -> #t)
(check-type (equal? (list (box 1)) (list (box 1))) : Bool -> #t)
(check-type (equal? (list (box 1)) (list (box 1.0))) : Bool -> #t)
(define-symbolic n integer? : Int)
(check-type (equal? n 1) : Bool -> (= 1 n))
(check-type (equal? (box n) (box 1)) : Bool -> (= 1 n))
(check-not-type (equal? n 1) : CBool)
(check-not-type (equal? (box n) (box 1)) : CBool)
(define-symbolic f g (~> integer? integer?) : ( Int Int))
(typecheck-fail
(define-symbolic f g (~> integer? integer?) : (C→ Int Int))
#:with-msg "symbolic value cannot have a concrete type")
(check-type f : ( Int Int))
(check-type g : ( Int Int))
(check-type (equal? f g) : Bool -> #f)
(check-type (f 1) : Int -> (f 1))
(check-type (eq? 1 #t) : Bool -> #f)
(check-type (eq? 1 1.0) : Bool -> #t) ; equal? transparent solvable values
(check-type (eq? (list 1) (list 1.0)) : Bool -> #t) ; transparent immutable values with eq? contents
(check-type (eq? (box 1) (box 1)) : Bool -> #f); but boxes are mutable, so eq? follows Racket
(check-type (eq? (list (box 1)) (list (box 1))) : Bool -> #f)
(check-type (eq? n 1) : Bool -> (= 1 n))
(check-type (eq? (box n) (box 1)) : Bool -> #f)
(check-type (eq? f g) : Bool -> #f) ; and procedures are opaque, so eq? follows Racket
(check-type (eq? f f) : Bool -> #t)
(check-type (distinct?) : Bool -> #t)
(check-type (distinct? 1) : Bool -> #t)
(check-type (distinct? (list 1 2) (list 3) (list 1 2)) : Bool -> #f)
(define-symbolic x y z integer? : Int)
(check-type (distinct? 3 z x y 2) : Bool -> (distinct? 2 3 x y z))
(define-symbolic b boolean? : Bool)
(check-type (distinct? 3 (bv 3 4) (list 1) (list x) y 2)
: Bool -> (&& (! (= 3 y)) (&& (! (= 1 x)) (! (= 2 y)))))
(clear-asserts!)
;; 4.2 Booleans, Integers, and Reals
;(define-symbolic b boolean? : Bool)
(check-type (boolean? b) : Bool -> #t)
(check-type (boolean? #t) : Bool -> #t)
(check-type (boolean? #f) : Bool -> #t)
(check-type (boolean? true) : Bool -> #t)
(check-type (boolean? false) : Bool -> #t)
(check-type (boolean? 1) : Bool -> #f)
(check-type (not b) : Bool -> (! b))
(check-type (nand) : CFalse -> #f)
(check-type (nand #t #t) : Bool -> #f)
(check-type (nand 1 2) : Bool -> #f)
(check-type (nor) : CTrue -> #t)
(check-type (nor #f #f) : Bool -> #t)
(check-type (nor 1 2) : Bool -> #f)
(check-type (nand #f #t) : Bool -> #t)
(check-type (nand #f (error 'ack "we don't get here")) : Bool -> #t)
(check-type (nor #f #t) : Bool -> #f)
(check-type (nor #t (error 'ack "we don't get here")) : Bool -> #f)
(check-type (implies #f #t) : Bool -> #t)
(check-type (implies #f #f) : Bool -> #t)
(check-type (implies #t #f) : Bool -> #f)
(check-type (implies #f (error 'ack "we don't get here")) : Bool -> #t)
;; (check-type (xor 11 #f) : Any -> 11)
;; (check-type (xor #f 22) : Any -> 22)
;; (check-type (xor 11 22) : Any -> #f)
;; (check-type (xor #f #f) : Any -> #f)
(check-type +inf.0 : CFloat)
(check-type -inf.0 : CFloat)
(check-type +nan.0 : CFloat)
(check-type -nan.0 : CFloat)
(check-type (number? 1) : Bool -> #t)
(typecheck-fail (number? 2+3i) #:with-msg "Unsupported literal")
(check-type (number? "hello") : Bool -> #f)
(check-type (real? 1) : Bool -> #t)
(check-type (real? +inf.0) : Bool -> #t)
(typecheck-fail (real? 2+3i) #:with-msg "Unsupported literal")
(typecheck-fail (real? 2.0+0.0i) #:with-msg "Unsupported literal")
(check-type (real? "hello") : Bool -> #f)
(check-type (integer? 1) : Bool -> #t)
(check-type (integer? 2.3) : Bool -> #f)
(check-type (integer? 4.0) : Bool -> #t)
(check-type (integer? +inf.0) : Bool -> #f)
(typecheck-fail (integer? 2+3i) #:with-msg "Unsupported literal")
(check-type (integer? "hello") : Bool -> #f)
(check-type (zero? 0) : CBool -> #t)
(check-type (zero? -0.0) : CBool -> #t)
(check-type (positive? 10) : CBool -> #t)
(check-type (positive? -10) : CBool -> #f)
(check-type (positive? 0.0) : CBool -> #f)
(check-type (negative? 10) : CBool -> #f)
(check-type (negative? -10) : CBool -> #t)
(check-type (negative? -0.0) : CBool -> #f)
(check-type (even? 10.0) : CBool -> #t)
(check-type (even? 11) : CBool -> #f)
(check-type +inf.0 : CNum)
(typecheck-fail (even? +inf.0) #:with-msg "expected.*Int")
(check-type (odd? 10.0) : Bool -> #f)
(check-type (odd? 11) : Bool -> #t)
(typecheck-fail (odd? +inf.0) #:with-msg "expected.*Int")
(check-type (inexact->exact 1) : CNum -> 1)
(check-type (inexact->exact 1.0) : CNum -> 1)
(check-type (exact->inexact 1) : CNum -> 1.0)
(check-type (exact->inexact 1.0) : CNum -> 1.0)
(check-type (+ 1 2) : CInt -> 3)
(typecheck-fail (+ 1.0 2+3i 5) #:with-msg "Unsupported literal")
(check-type (+) : CInt -> 0)
(check-type (- 5 3.0) : CInt -> 2.0)
(check-type (- 1) : CInt -> -1)
(typecheck-fail (- 2+7i 1 3) #:with-msg "Unsupported literal")
(check-type (* 2 3) : CInt -> 6)
(check-type (* 8.0 9) : CInt -> 72.0)
(typecheck-fail (* 1+2i 3+4i) #:with-msg "Unsupported literal")
(check-type (/ 3 4) : CNum -> 3/4)
(check-type (/ 81 3 3) : CNum -> 9)
(check-type (/ 10.0) : CNum -> 0.1)
(typecheck-fail (/ 1+2i 3+4i) #:with-msg "Unsupported literal")
(check-type (quotient 10 3) : CInt -> 3)
(check-type (quotient -10.0 3) : CInt -> -3.0)
(typecheck-fail (quotient +inf.0 3) #:with-msg "expected.*Int")
(check-type (remainder 10 3) : CInt -> 1)
(check-type (remainder -10.0 3) : CInt -> -1.0)
(check-type (remainder 10.0 -3) : CInt -> 1.0)
(check-type (remainder -10 -3) : CInt -> -1)
(typecheck-fail (remainder +inf.0 3) #:with-msg "expected.*Int")
(check-type (modulo 10 3) : CInt -> 1)
(check-type (modulo -10.0 3) : CInt -> 2.0)
(check-type (modulo 10.0 -3) : CInt -> -2.0)
(check-type (modulo -10 -3) : CInt -> -1)
(typecheck-fail (modulo +inf.0 3) #:with-msg "expected.*Int")
(check-type (abs 1.0) : CInt -> 1.0)
(check-type (abs -1) : CInt -> 1)
(check-type (max 1 3 2) : CInt -> 3)
(check-type (max 1 3 2.0) : CInt -> 3) ; Racket coerces to inexact, but Rosette does not?
(check-type (min 1 3 2) : CInt -> 1)
(check-type (min 1 3 2.0) : CInt -> 1) ; Racket coerces to inexact, but Rosette does not?
(check-type (floor 17/4) : CNum -> 4)
(check-type (floor -17/4) : CNum -> -5)
(check-type (floor 2.5) : CNum -> 2.0)
(check-type (floor -2.5) : CNum -> -3.0)
(check-type (floor +inf.0) : CNum -> +inf.0)
(check-type (ceiling 17/4) : CNum -> 5)
(check-type (ceiling -17/4) : CNum -> -4)
(check-type (ceiling 2.5) : CNum -> 3.0)
(check-type (ceiling -2.5) : CNum -> -2.0)
(check-type (ceiling +inf.0) : CNum -> +inf.0)
(check-type (truncate 17/4) : CNum -> 4)
(check-type (truncate -17/4) : CNum -> -4)
(check-type (truncate 2.5) : CNum -> 2.0)
(check-type (truncate -2.5) : CNum -> -2.0)
(check-type (truncate +inf.0) : CNum -> +inf.0)
(check-type (= 1 1.0) : CBool -> #t)
(check-type (= 1 2) : CBool -> #f)
(typecheck-fail (= 2+3i 2+3i 2+3i) #:with-msg "Unsupported literal")
(check-type (< 1 1) : CBool -> #f)
(check-type (< 1 2 3) : CBool -> #t)
(check-type (< 1 +inf.0) : CBool -> #t)
(check-type (< 1 +nan.0) : CBool -> #f)
(check-type (<= 1 1) : CBool -> #t)
(check-type (<= 1 2 1) : CBool -> #f)
(check-type (> 1 1) : CBool -> #f)
(check-type (> 3 2 1) : CBool -> #t)
(check-type (> +inf.0 1) : CBool -> #t)
(check-type (> +nan.0 1) : CBool -> #f)
(check-type (>= 1 1) : CBool -> #t)
(check-type (>= 1 2 1) : CBool -> #f)
(check-type (expt 2 3) : CInt -> 8)
(check-type (expt 4 0.5) : CNum -> 2.0)
(check-type (expt +inf.0 0) : CInt -> 1)
(check-type pi : CNum -> 3.141592653589793)
(check-type (sgn 10) : CInt -> 1)
(check-type (sgn -10.0) : CInt -> -1.0)
(check-type (sgn 0) : CInt -> 0)
(check-type (sgn +nan.0) : CNum -> +nan.0)
(clear-asserts!)
;; 4.2.1 Additional Logic Operators
(check-type (! #f) : Bool -> #t)
(check-type (! #t) : Bool -> #f)
; this typechecks only when b is true
(check-type (! (assert-type (if b #f 3) : Bool)) : Bool -> #t)
; so Rosette emits a corresponding assertion
(check-type (asserts) : (CListof Bool) -> (list b))
(clear-asserts!)
(check-type (&&) : Bool -> #t)
(check-type (||) : Bool -> #f)
; no shortcircuiting
(check-type (&& #f (begin (displayln "hello") #t)) : Bool -> #f)
(define-symbolic a boolean? : Bool)
; this typechecks only when b is true
(check-type (&& a (assert-type (if b #t 1) : Bool)) : Bool -> a)
; so Rosette emits a corresponding assertion
(check-type (asserts) : (CListof Bool) -> (list b))
(clear-asserts!)
; no shortcircuiting
(check-type (=> #f (begin (displayln "hello") #f)) : Bool -> #t)
; this typechecks only when b is true
(check-type (<=> a (assert-type (if b #t 1) : Bool)) : Bool -> a)
; so Rosette emits a corresponding assertion
(check-type (asserts) : (CListof Bool) -> (list b))
(clear-asserts!)
(current-bitwidth #f)
(define-symbolic a1 b1 integer? : Int)
(check-type (forall (list) (= a1 b1)) : Bool -> (= a1 b1))
(define f1 (forall (list a1) (exists (list b1) (= a1 (+ a1 b1))))) ; no free constants
; so the model has no bindings
(define sol1 (solve (assert f1)))
(check-type sol1 : CSolution) ; -> (sat) ; TODO: how to check empty model?
(check-type (sat? sol1) : Bool -> #t)
(define g1 (forall (list a1) (= a1 (+ a1 b1)))) ; b is free in g
; so the model has a binding for b
(define sol2 (solve (assert g1)))
(check-type sol2 : CSolution)
(check-type (sat? sol2) : Bool -> #t)
(check-type (evaluate b1 sol2) : Int -> 0)
(define h (exists (list a1) (forall (list a1) (= a1 (+ a1 a1))))) ; body refers to the innermost a
; so h is unsatisfiable.
(check-type (solve (assert h)) : CSolution -> (unsat))