start host lang param experiment

This commit is contained in:
Stephen Chang 2016-10-31 13:56:24 -04:00
parent 4f400b5e0a
commit 297e5df6ae
26 changed files with 4440 additions and 1 deletions

View File

@ -76,7 +76,10 @@
;; extract-filename : PathString -> String
(define (extract-filename f)
(path->string (path-replace-suffix (file-name-from-path f) "")))
(define-syntax-parameter stx (syntax-rules ())))
(define-syntax-parameter stx (syntax-rules ()))
;; parameter is an identifier transformer
(define current-host-lang (make-parameter mk--)))
;; non-Turnstile define-typed-syntax
;; TODO: potentially confusing? get rid of this?

View File

@ -0,0 +1,97 @@
#lang turnstile
(extends "rosette3.rkt" ; extends typed rosette
#:except bv bveq bvslt bvult bvsle bvule bvsgt bvugt bvsge bvuge)
(require (prefix-in ro: rosette)) ; untyped
(require (only-in sdsl/bv/lang/bvops bvredand bvredor bv bv*)
(prefix-in bv: (only-in sdsl/bv/lang/bvops BV)))
(require sdsl/bv/lang/core (prefix-in bv: sdsl/bv/lang/form))
(provide Prog Lib
(typed-out [bv : (Ccase-> (C→ CInt CBV)
(C→ CInt CBVPred CBV)
(C→ CInt CPosInt CBV))]
[bv* : (Ccase-> (C→ BV)
(C→ CBVPred BV))]
[bvredor : (C→ BV BV)]
[bvredand : (C→ BV BV)])
current-bvpred define-fragment bvlib thunk)
;; this must be a macro in order to support Racket's overloaded set/get
;; parameter patterns
(define-typed-syntax current-bvpred
[c-bvpred:id
--------
[ [_ bv:BV : (CParamof CBVPred)]]]
[(_)
--------
[ [_ (bv:BV) : CBVPred]]]
[(_ e)
[ [e e- : CBVPred]]
--------
[ [_ (bv:BV e-) : CUnit]]])
(define-syntax-rule (bv:bool->bv b)
(ro:if b
(bv (rosette3:#%datum . 1))
(bv (rosette3:#%datum . 0))))
(define-simple-macro (define-comparators id ...)
#:with (op ...) (stx-map (lambda (o) (format-id o "ro:~a" o)) #'(id ...))
#:with (id/tc ...) (generate-temporaries #'(id ...))
(begin-
(define- (id x y) (bv:bool->bv (ro:#%app op x y))) ...
(provide (rename-out [id/tc id] ...))
(define-primop id/tc id (C→ BV BV BV)) ...))
(define-comparators bveq bvslt bvult bvsle bvule bvsgt bvugt bvsge bvuge)
(define-base-types Prog Lib)
(define-typed-syntax define-fragment
[(_ (id param ...) #:implements spec #:library lib-expr)
--------
[_ (define-fragment (id param ...)
#:implements spec #:library lib-expr #:minbv (rosette3:#%datum . 4))]]
[(_ (id param ...) #:implements spec #:library lib-expr #:minbv minbv)
[ [spec spec- : ty_spec]]
#:fail-unless (C→? #'ty_spec) "spec must be a function"
[ [lib-expr lib-expr- : Lib]]
[ [minbv minbv- : Int]]
#:with id-stx (format-id #'id "~a-stx" #'id #:source #'id)
--------
[_ (begin-
(define-values- (id-internal id-stx-internal)
(bv:synthesize-fragment (id param ...)
#:implements spec-
#:library lib-expr-
#:minbv minbv-))
(define-syntax id
(make-rename-transformer ( id-internal : ty_spec)))
(define-syntax id-stx
(make-rename-transformer ( id-stx-internal : CStx)))
)]])
(define-typed-syntax bvlib
[(_ [(~and ids (id ...)) n] ...)
#:fail-unless (stx-andmap brace? #'(ids ...))
"given ops must be enclosed with braces"
[ [n n- : Int] ...]
[ [id id- : ty_id] ... ...]
#:fail-unless (stx-andmap (lambda (t) (or (C→? t) (Ccase->? t))) #'(ty_id ... ...))
"given op must be a function"
;; outer ~and wrapper is a syntax-parse workaround
#:with ((~and (~or (~C→ ty ...)
(~and (~Ccase-> (~C→ ty* ...) ...)
(~parse (ty ...) #'(ty* ... ...))))) ...)
#'(ty_id ... ...)
#:fail-unless (stx-andmap τ⊑BV? #'(ty ... ...))
"given op must have BV inputs and output"
--------
[ [_ (bv:bvlib [{id- ...} n-] ...) : Lib]]])
(begin-for-syntax
(define BV* ((current-type-eval) #'BV))
(define (τ⊑BV? τ)
(typecheck? τ BV*)))
(define-syntax-rule (thunk e) (rosette3:λ () e))

View File

@ -0,0 +1,14 @@
#lang turnstile
(require
(prefix-in t/ro: (only-in "../rosette3.rkt" U))
(prefix-in ro: rosette/lib/angelic))
(provide choose*)
(define-typed-syntax choose*
[(ch e ...+)
[ [e e- : ty]] ...
#:with (e/disarmed ...) (stx-map replace-stx-loc #'(e- ...) #'(e ...))
--------
;; the #'choose* identifier itself must have the location of its use
;; see define-synthax implementation, specifically syntax/source in utils
[ [_ (#,(syntax/loc #'ch ro:choose*) e/disarmed ...) : (t/ro:U ty ...)]]])

View File

@ -0,0 +1,23 @@
#lang turnstile
(require
(prefix-in t/ro: (only-in "../rosette3.rkt" U ~C→ C→))
(prefix-in ro: rosette/lib/lift))
(provide define-lift)
(define-typed-syntax define-lift
[(_ x:id [(pred? ...) racket-fn:id])
[ [pred? pred?- : (t/ro:~C→ _ ...)]] ...
[ [racket-fn racket-fn- : (t/ro:~C→ ty1 ty2)]]
#:with y (generate-temporary #'x)
--------
[_ (begin-
(define-syntax- x (make-rename-transformer ( y : (t/ro:C→ (t/ro:U ty1) (t/ro:U ty2)))))
(ro:define-lift y [(pred?- ...) racket-fn-]))]]
[(_ x:id [pred? racket-fn:id])
[ [pred? pred?- : (t/ro:~C→ _ ...)]]
[ [racket-fn racket-fn- : (t/ro:~C→ ty1 ty2)]]
#:with y (generate-temporary #'x)
--------
[_ (begin-
(define-syntax- x (make-rename-transformer ( y : (t/ro:C→ (t/ro:U ty1) (t/ro:U ty2)))))
(ro:define-lift y [pred?- racket-fn-]))]])

View File

@ -0,0 +1,17 @@
#lang turnstile
(require
(prefix-in t/ro: (only-in "../rosette3.rkt" CNat CSolution CPict))
(prefix-in ro: rosette/lib/render))
(provide render)
(define-typed-syntax render
[(_ s)
[ [s s- : t/ro:CSolution]]
--------
[ [_ (ro:render s-) : t/ro:CPict]]]
[(_ s sz)
[ [s s- : t/ro:CSolution]]
[ [sz sz- : t/ro:CNat]]
--------
[ [_ (ro:render s- sz-) : t/ro:CPict]]])

View File

@ -0,0 +1,80 @@
#lang turnstile
(require
(only-in "../rosette3.rkt" rosette-typed-out)
(prefix-in
t/ro:
(only-in "../rosette3.rkt" U Int Bool C→ CSolution Unit CSyntax CListof))
(prefix-in ro: rosette/lib/synthax))
(provide (rosette-typed-out [print-forms : (t/ro:C→ t/ro:CSolution t/ro:Unit)])
??)
(provide generate-forms choose)
(define-typed-syntax ??
[(qq)
#:with ??/progsrc (datum->syntax #'here 'ro:?? #'qq)
--------
[ [_ (??/progsrc) : t/ro:Int]]]
[(qq pred?)
#:with ??/progsrc (datum->syntax #'here 'ro:?? #'qq)
[ [pred? pred?- ( : _) ( typefor ty) ( solvable? s?) ( function? f?)]]
#:fail-unless (syntax-e #'s?)
(format "Expected a Rosette-solvable type, given ~a."
(syntax->datum #'pred?))
#:fail-when (syntax-e #'f?)
(format "Expected a non-function Rosette type, given ~a."
(syntax->datum #'pred?))
--------
[ [_ (??/progsrc pred?-) : ty]]])
(define-syntax print-forms
(make-variable-like-transformer
(assign-type #'ro:print-forms #'(t/ro:C→ t/ro:CSolution t/ro:Unit))))
(define-syntax generate-forms
(make-variable-like-transformer
(assign-type #'ro:generate-forms #'(t/ro:C→ t/ro:CSolution (t/ro:CListof t/ro:CSyntax)))))
(define-typed-syntax choose
[(ch e ...+)
[ [e e- : ty]] ...
#:with (e/disarmed ...) (stx-map replace-stx-loc #'(e- ...) #'(e ...))
--------
;; the #'choose identifier itself must have the location of its use
;; see define-synthax implementation, specifically syntax/source in utils
[ [_ (#,(syntax/loc #'ch ro:choose) e/disarmed ...) : (t/ro:U ty ...)]]])
;; TODO: not sure how to handle define-synthax
;; it defines a macro, but may refer to itself in #:base and #:else
;; - so must expand "be" and "ee", but what to do about self reference?
;; - the current letrec-like implementation results in an #%app of the the f macro
;; which isnt quite right
#;(define-typed-syntax define-synthax #:datum-literals (: -> )
#;[(_ x:id ([pat e] ...+))
[ [e e- : τ]] ...
#:with y (generate-temporary #'x)
--------
[_ (begin-
(define-syntax- x (make-rename-transformer ( y : t/ro:Int)))
(ro:define-synthax y ([pat e-] ...)))]]
[(_ (f [x:id : ty] ... [k:id : tyk] -> ty_out) #:base be #:else ee)
#:with (e ...) #'(be ee)
[() ([x x- : ty] ... [k k- : tyk] [f f- : (t/ro:C→ ty ... tyk ty_out)])
[e e- : ty_e] ...]
#:with (be- ee-) #'(e- ...)
#:with f* (generate-temporary)
#:with app-f (format-id #'f "apply-~a" #'f)
--------
[_ (begin-
(ro:define-synthax (f- x- ... k-) #:base be- #:else ee-)
(define-syntax- app-f
(syntax-parser
[(_ . es)
;; TODO: typecheck es
#:with es- (stx-map expand/df #'es)
; #:with es/fixsrc (stx-map replace-stx-loc #'es- #'es)
(assign-type #'(f- . es) #'ty_out)])))]])
; (⊢ f- : (t/ro:C→ ty ... tyk ty_out))
; #;(ro:define-synthax (f- x- ... k-)
; #:base be- #:else ee-))]])

View File

@ -0,0 +1,39 @@
#lang turnstile
(require
(prefix-in t/ro: (only-in "../rosette3.rkt"
λ ann begin C→ Nothing Bool CSolution))
(prefix-in ro: rosette/query/debug))
(provide define/debug debug)
(define-typed-syntax define/debug #:datum-literals (: -> )
[(_ x:id e)
[ [e e- : τ]]
#:with y (generate-temporary #'x)
--------
[_ (begin-
(define-syntax- x (make-rename-transformer ( y : τ)))
(ro:define/debug y e-))]]
[(_ (f [x : ty] ... (~or ->) ty_out) e ...+)
; [⊢ [e ≫ e- ⇒ : ty_e]]
#:with f- (generate-temporary #'f)
--------
[_ (begin-
(define-syntax- f (make-rename-transformer ( f- : (t/ro:C→ ty ... ty_out))))
(ro:define/debug f-
(t/ro:λ ([x : ty] ...)
(t/ro:ann (t/ro:begin e ...) : ty_out))))]])
(define-typed-syntax debug
[(_ (pred? ...+) e)
[ [pred? pred?- ( : _) ( typefor ty) ( solvable? s?) ( function? f?)]] ...
#:fail-unless (stx-andmap syntax-e #'(s? ...))
(format "Expected a Rosette-solvable type, given ~a."
(syntax->datum #'(pred? ...)))
#:fail-when (stx-ormap syntax-e #'(f? ...))
(format "Expected a non-function Rosette type, given ~a."
(syntax->datum #'(pred? ...)))
[ [e e- : τ]]
--------
[ [_ (ro:debug (pred?- ...) e-) : t/ro:CSolution]]])

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,404 @@
#lang s-exp "../../../rosette/bv3.rkt"
(require syntax/parse/define
(only-in racket/base for-syntax) (for-syntax racket/base))
(require "../../rackunit-typechecking.rkt")
; The 25 Hacker's Delight benchmarks from the following paper:
; Sumit Gulwani, Susmit Jha, Ashish Tiwari, and Ramarathnam Venkatesan.
; 2011. Synthesis of loop-free programs. In Proceedings of the 32nd ACM
; SIGPLAN Conference on Programming Language Design and Implementation (PLDI '11).
;
; The first 20 benchmarks are also used in the SyGuS competition: http://www.sygus.org
(current-bvpred (bitvector 32))
(check-type (thunk (bv 1)) : (C→ BV))
; Constants.
(define bv1 (thunk (bv 1)))
(define bv2 (thunk (bv 2)))
(define bvsz (thunk (bv (sub1 (bitvector-size (current-bvpred))))))
(check-type bv1 : (C→ BV))
(check-type (bv1) : BV -> (bv 1))
(check-type ((bitvector 4) (bv1)) : Bool -> #f)
(check-type ((bitvector 32) (bv1)) : Bool -> #t)
(check-type bv2 : (C→ BV))
(check-type bvsz : (C→ BV))
(check-type (bvsub (bv 1) (bv1)) : BV -> (bv 0))
(check-type ((bitvector 32) (bvsub (bv 1) (bv1))) : Bool -> #t)
; Mask off the rightmost 1-bit.
(define (p1 [x : BV] -> BV)
(let* ([o1 (bvsub x (bv 1))]
[o2 (bvand x o1)])
o2))
(check-type (p1 (bv 1)) : BV -> (bv 0))
(check-type ((bitvector 32) (p1 (bv 1))) : Bool -> #t)
; Test whether an unsigned integer is of the form 2^n-1.
(define (p2 [x : BV] -> BV)
(let* ([o1 (bvadd x (bv 1))]
[o2 (bvand x o1)])
o2))
; Isolate the right most 1-bit.
(define (p3 [x : BV] -> BV)
(let* ([o1 (bvneg x)]
[o2 (bvand x o1)])
o2))
; Form a mask that identifies the rightmost 1-bit and trailing 0s.
(define (p4 [x : BV] -> BV)
(let* ([o1 (bvsub x (bv 1))]
[o2 (bvxor x o1)])
o2))
; Right propagate rightmost 1-bit.
(define (p5 [x : BV] -> BV)
(let* ([o1 (bvsub x (bv 1))]
[o2 (bvor x o1)])
o2))
; Turn on the right-most 0-bit in a word.
(define (p6 [x : BV] -> BV)
(let* ([o1 (bvadd x (bv 1))]
[o2 (bvor x o1)])
o2))
; Isolate the right most 0 bit of a given bitvector.
(define (p7 [x : BV] -> BV)
(let* ([o1 (bvnot x)]
[o2 (bvadd x (bv 1))]
[o3 (bvand o1 o2)])
o3))
; Form a mask that identifies the trailing 0s.
(define (p8 [x : BV] -> BV)
(let* ([o1 (bvsub x (bv 1))]
[o2 (bvnot x)]
[o3 (bvand o1 o2)])
o3))
; Absolute value function.
(define (p9 [x : BV] -> BV)
(let* ([o1 (bvashr x (bv 31))]
[o2 (bvxor x o1)]
[o3 (bvsub o2 o1)])
o3))
; Test if nlz(x) == nlz(y) where nlz is number of leading zeroes.
(define (p10 [x : BV] [y : BV] -> BV)
(let* ([o1 (bvand x y)]
[o2 (bvxor x y)]
[o3 (bvule o2 o1)])
o3))
; Test if nlz(x) < nlz(y) where nlz is number of leading zeroes.
(define (p11 [x : BV] [y : BV] -> BV)
(let* ([o1 (bvnot y)]
[o2 (bvand x o1)]
[o3 (bvugt o2 y)])
o3))
; Test if nlz(x) <= nlz(y) where nlz is number of leading zeroes.
(define (p12 [x : BV] [y : BV] -> BV)
(let* ([o1 (bvnot x)]
[o2 (bvand y o1)]
[o3 (bvule o2 x)])
o3))
; Sign function.
(define (p13 [x : BV] -> BV)
(let* ([o1 (bvneg x)]
[o2 (bvlshr o1 (bv 31))]
[o3 (bvashr x (bv 31))]
[o4 (bvor o2 o3)])
o4))
; Floor of average of two integers without over-flowing.
(define (p14 [x : BV] [y : BV] -> BV)
(let* ([o1 (bvand x y)]
[o2 (bvxor x y)]
[o3 (bvlshr o2 (bv 1))]
[o4 (bvadd o1 o3)])
o4))
; Ceil of average of two integers without over-flowing.
(define (p15 [x : BV] [y : BV] -> BV)
(let* ([o1 (bvor x y)]
[o2 (bvxor x y)]
[o3 (bvlshr o2 (bv 1))]
[o4 (bvsub o1 o3)])
o4))
; The max function.
(define (p16 [x : BV] [y : BV] -> BV)
(if (equal? (bv 1) (bvsge x y)) x y))
; Turn-off the rightmost contiguous string of 1 bits.
(define (p17 [x : BV] -> BV)
(let* ([o1 (bvsub x (bv 1))]
[o2 (bvor x o1)]
[o3 (bvadd o2 (bv 1))]
[o4 (bvand o3 x)])
o4))
; Test whether an unsigned integer is of the form 2^n.
(define (p18 [x : BV] -> BV)
(let* ([o1 (bvsub x (bv 1))]
[o2 (bvand o1 x)]
[o3 (bvredor x)]
[o4 (bvredor o2)]
[o5 (bvnot o4)]
[o6 (bvand o5 o3)])
o6))
; Exchanging 2 fields A and B of the same register
; x where m is mask which identifies field B and k
; is number of bits from end of A to start of B.
(define (p19 [x : BV] [m : BV] [k : BV] -> BV)
(let* ([o1 (bvlshr x k)]
[o2 (bvxor x o1)]
[o3 (bvand o2 m)]
[o4 (bvshl o3 k)]
[o5 (bvxor o4 o3)]
[o6 (bvxor o5 x)])
o6))
; Next higher unsigned number with the same number of 1 bits.
(define (p20 [x : BV] -> BV)
(let* ([o1 (bvneg x)]
[o2 (bvand x o1)]
[o3 (bvadd x o2)]
[o4 (bvxor x o2)]
[o5 (bvlshr o4 (bv 2))]
[o6 (bvudiv o5 o2)]
[o7 (bvor o6 o3)])
o7))
; Cycling through 3 values a, b, c.
(define (p21 [x : BV] [a : BV] [b : BV] [c : BV] -> BV)
(let* ([o1 (bveq x c)]
[o2 (bvneg o1)]
[o3 (bvxor a c)]
[o4 (bveq x a)]
[o5 (bvneg o4)]
[o6 (bvxor b c)]
[o7 (bvand o2 o3)]
[o8 (bvand o5 o6)]
[o9 (bvxor o7 o8)]
[o10 (bvxor o9 c)])
o10))
; Compute parity.
(define (p22 [x : BV] -> BV)
(let* ([o1 (bvlshr x (bv 1))]
[o2 (bvxor o1 x)]
[o3 (bvlshr o2 (bv 2))]
[o4 (bvxor o2 o3)]
[o5 (bvand o4 (bv #x11111111))]
[o6 (bvmul o5 (bv #x11111111))]
[o7 (bvlshr o6 (bv 28))]
[o8 (bvand o7 (bv 1))])
o8))
; Counting number of bits.
(define (p23 [x : BV] -> BV)
(let* ([o1 (bvlshr x (bv 1))]
[o2 (bvand o1 (bv #x55555555))]
[o3 (bvsub x o2)]
[o4 (bvand o3 (bv #x33333333))]
[o5 (bvlshr o3 (bv 2))]
[o6 (bvand o5 (bv #x33333333))]
[o7 (bvadd o4 o6)]
[o8 (bvlshr o7 (bv 4))]
[o9 (bvadd o8 o7)]
[o10 (bvand o9 (bv #x0f0f0f0f))])
o10))
; Round up to the next higher power of 2.
(define (p24 [x : BV] -> BV)
(let* ([o1 (bvsub x (bv 1))]
[o2 (bvlshr o1 (bv 1))]
[o3 (bvor o1 o2)]
[o4 (bvlshr o3 (bv 2))]
[o5 (bvor o3 o4)]
[o6 (bvlshr o5 (bv 4))]
[o7 (bvor o5 o6)]
[o8 (bvlshr o7 (bv 8))]
[o9 (bvor o7 o8)]
[o10 (bvlshr o9 (bv 16))]
[o11 (bvor o9 o10)]
[o12 (bvadd o11 (bv 1))])
o12))
; Compute higher order half of product of x and y.
(define (p25 [x : BV] [y : BV] -> BV)
(let* ([o1 (bvand x (bv #xffff))]
[o2 (bvlshr x (bv 16))]
[o3 (bvand y (bv #xffff))]
[o4 (bvlshr y (bv 16))]
[o5 (bvmul o1 o3)]
[o6 (bvmul o2 o3)]
[o7 (bvmul o1 o4)]
[o8 (bvmul o2 o4)]
[o9 (bvlshr o5 (bv 16))]
[o10 (bvadd o6 o9)]
[o11 (bvand o10 (bv #xffff))]
[o12 (bvlshr o10 (bv 16))]
[o13 (bvadd o7 o11)]
[o14 (bvlshr o13 (bv 16))]
[o15 (bvadd o14 o12)]
[o16 (bvadd o15 o8)])
o16))
(define-simple-macro (check-equal/rand/bv f)
#:with out (syntax/loc this-syntax
(check-equal/rand f #:process (λ ([x : CInt]) (bv x))))
out)
;; Mask off the rightmost 1-bit. < 1 sec.
(define-fragment (p1* x)
#:implements p1
#:library (bvlib [{bv1 bvand bvsub} 1]))
(check-equal/rand/bv p1)
; Test whether an unsigned integer is of the form 2^n-1. < 1 sec.
(define-fragment (p2* x)
#:implements p2
#:library (bvlib [{bv1 bvand bvadd} 1]))
(check-equal/rand/bv p2)
; Isolate the right most 1-bit. < 1 sec.
(define-fragment (p3* x)
#:implements p3
#:library (bvlib [{bvand bvneg} 1]))
(check-equal/rand/bv p3)
;; Form a mask that identifies the rightmost 1-bit and trailing 0s. < 1 sec.
(define-fragment (p4* x)
#:implements p4
#:library (bvlib [{bv1 bvsub bvxor} 1]))
(check-equal/rand/bv p4)
; Right propagate rightmost 1-bit. < 1 sec.
(define-fragment (p5* x)
#:implements p5
#:library (bvlib [{bv1 bvsub bvor} 1]))
(check-equal/rand/bv p5)
; Turn on the right-most 0-bit in a word. < 1 sec.
(define-fragment (p6* x)
#:implements p6
#:library (bvlib [{bv1 bvor bvadd} 1]))
(check-equal/rand/bv p6)
; Isolate the right most 0 bit of a given bitvector. < 1 sec.
(define-fragment (p7* x)
#:implements p7
#:library (bvlib [{bvand bvadd bvnot bv1} 1]))
(check-equal/rand/bv p7)
; Form a mask that identifies the trailing 0s. < 1 sec.
(define-fragment (p8* x)
#:implements p8
#:library (bvlib [{bv1 bvsub bvand bvnot} 1]))
(check-equal/rand/bv p8)
; Absolute value function. ~ 1 sec.
(define-fragment (p9* x)
#:implements p9
#:library (bvlib [{bvsz bvsub bvxor bvashr} 1]))
(check-equal/rand/bv p9)
; Test if nlz(x) == nlz(y) where nlz is number of leading zeroes. < 1 sec.
(define-fragment (p10* x y)
#:implements p10
#:library (bvlib [{bvand bvxor bvule} 1]))
(check-equal/rand/bv p10)
; Test if nlz(x) < nlz(y) where nlz is number of leading zeroes. < 1 sec.
(define-fragment (p11* x y)
#:implements p11
#:library (bvlib [{bvnot bvand bvugt} 1]))
(check-equal/rand/bv p11)
; Test if nlz(x) <= nlz(y) where nlz is number of leading zeroes. < 1 sec.
(define-fragment (p12* x y)
#:implements p12
#:library (bvlib [{bvand bvnot bvule} 1]))
(check-equal/rand/bv p12)
; Sign function. ~ 1.4 sec.
(define-fragment (p13* x)
#:implements p13
#:library (bvlib [{bvsz bvneg bvlshr bvashr bvor} 1])
#:minbv 32)
(check-equal/rand/bv p13)
; Floor of average of two integers without over-flowing. ~ 2.5 sec.
(define-fragment (p14* x y)
#:implements p14
#:library (bvlib [{bv1 bvand bvlshr bvxor bvadd} 1]))
(check-equal/rand/bv p14)
; Ceil of average of two integers without over-flowing. ~ 1 sec.
(define-fragment (p15* x y)
#:implements p15
#:library (bvlib [{bv1 bvor bvlshr bvxor bvsub} 1]))
(check-equal/rand/bv p15)
; Compute max of two integers. Bug in the PLDI'11 paper: bvuge should be bvge.
; ~ 1.3 sec.
(define-fragment (p16* x y)
#:implements p16
#:library (bvlib [{bvneg bvsge bvand} 1] [{bvxor} 2]))
(check-equal/rand/bv p16)
; Turn-off the rightmost contiguous string of 1 bits. ~ 1.8 sec.
(define-fragment (p17* x)
#:implements p17
#:library (bvlib [{bv1 bvand bvor bvadd bvsub} 1]))
(check-equal/rand/bv p17)
; Test whether an unsigned integer is of the form 2^n. ~ 1.6 sec.
(define-fragment (p18* x)
#:implements p18
#:library (bvlib [{bvand bvredor} 2] [{bvsub bvnot bv1} 1]))
(check-equal/rand/bv p18)
; x where m is mask which identifies field B and k
; is number of bits from end of A to start of B. ~ 3.5 sec.
(define-fragment (p19* x m k)
#:implements p19
#:library (bvlib [{bvlshr bvshl bvand} 1] [{bvxor} 3]))
(check-equal/rand/bv p19)
; Next higher unsigned number with the same number of 1 bits. ~ 600 sec.
(define-fragment (p20* x)
#:implements p20
#:library (bvlib [{bv2 bvneg bvand bvadd bvxor bvlshr bvudiv bvor} 1]))
(check-equal/rand/bv p20)

View File

@ -0,0 +1,30 @@
#lang s-exp "../../../rosette/bv3.rkt"
(require "../../rackunit-typechecking.rkt")
(check-type current-bvpred : (CParamof CBVPred))
(check-type (current-bvpred) : BVPred -> (bitvector 4))
(check-type (current-bvpred (bitvector 5)) : CUnit -> (void))
(check-type (current-bvpred) : BVPred -> (bitvector 5))
(check-type (current-bvpred (bitvector 4)) : CUnit -> (void))
(check-type (bv 1) : BV)
(check-type ((bitvector 4) (bv 1)) : Bool -> #t)
(check-type ((bitvector 1) (bv 1)) : Bool -> #f)
(check-type (bv 2 (bitvector 3)) : BV)
(check-type ((bitvector 3) (bv 2 (bitvector 3))) : Bool -> #t)
(check-type (bv*) : BV)
(check-type (if 1 (bv 1) (bv 0)) : BV -> (bv 1))
(check-type (if #f (bv 1) (bv 0)) : BV -> (bv 0))
(define-symbolic i integer?)
(define-symbolic b boolean?)
(check-type (if i (bv 1) (bv 0)) : BV -> (bv 1))
(check-type (if b (bv 1) (bv 0)) : BV -> (if b (bv 1) (bv 0)))
(check-type (bvredor (bv 1)) : BV)
(check-type (bvredand (bv 1)) : BV)
(check-type bveq : ( BV BV BV))
(check-type (bveq (bv 1) (bv 1)) : BV -> (bv 1))
(check-type (bveq (bv 1) (bv 0)) : BV -> (bv 0))

View File

@ -0,0 +1,17 @@
#lang racket/base
(provide check-type+asserts)
(require turnstile/turnstile
"../check-asserts.rkt"
(only-in "../../../rosette/rosette3.rkt" CListof Bool CUnit))
(define-typed-syntax check-type+asserts #:datum-literals (: ->)
[(_ e : τ-expected -> v asserts)
[ [e e- : τ-expected]]
--------
[ [_ (check-equal?/asserts e-
(add-expected v τ-expected)
(add-expected asserts (CListof Bool)))
: CUnit]]])

View File

@ -0,0 +1,43 @@
#lang s-exp "../../rosette/fsm3.rkt"
(require "../../rackunit-typechecking.rkt")
(define m
(automaton init
[init : (c more)]
[more : (a more)
(d more)
(r end)]
[end : ]))
(define rx #px"^c[ad]+r$")
(typecheck-fail (automaton init)
#:with-msg "initial state init is not declared state")
(typecheck-fail (automaton init [init : (c more)])
#:with-msg "unbound identifier")
(typecheck-fail (automaton init [init : (c "more")])
#:with-msg "expected State, given String")
(define M
(automaton init
[init : (c (? s1 s2))]
[s1 : (a (? s1 s2 end reject))
(d (? s1 s2 end reject))
(r (? s1 s2 end reject))]
[s2 : (a (? s1 s2 end reject))
(d (? s1 s2 end reject))
(r (? s1 s2 end reject))]
[end : ]))
(check-type (M '(c a r)) : Bool) ; symbolic result
(check-type (if (M '(c a r)) 1 2) : Int)
;; example commands
(check-type (m '(c a r)) : Bool -> #t)
(check-type (m '(c d r)) : Bool -> #t)
(check-type (m '(c a d a r)) : Bool -> #t)
(check-type (m '(c a d a)) : Bool -> #f)
(check-type (verify-automaton m #px"^c[ad]+r$") : (List Symbol) -> '(c r))
(check-type (debug-automaton m #px"^c[ad]+r$" '(c r)) : Pict)
(check-type (synthesize-automaton M #px"^c[ad]+r$") : Unit)

View File

@ -0,0 +1,92 @@
#lang s-exp "../../rosette/ifc3.rkt"
(require "../../rackunit-typechecking.rkt")
#;(define (cex-case name ended? prog [k #f])
(test-case name (check-pred EENI-witness? (verify-EENI* init ended? mem≈ prog k))))
(define p0 (program 3 (list Halt Noop Push Pop Add* Load* Store*AB)))
(check-type p0 : Prog)
;; expected:
;; m0 initial:
;; (machine [pc = 0@⊥]
;; [stack = ()]
;; [mem = (0@⊥ 0@⊥)]
;; [insts = ((Push -16@⊥) (Push 1@) (Store*AB))]
;; m0 final:
;; (machine [pc = 3@⊥]
;; [stack = ()]
;; [mem = (0@⊥ -16@⊥)]
;; [insts = ((Push -16@⊥) (Push 1@) (Store*AB))]
;; m1 initial:
;; (machine [pc = 0@⊥]
;; [stack = ()]
;; [mem = (0@⊥ 0@⊥)]
;; [insts = ((Push -16@⊥) (Push 0@) (Store*AB))]
;; m1 final:
;; (machine [pc = 3@⊥]
;; [stack = ()]
;; [mem = (-16@⊥ 0@⊥)]
;; [insts = ((Push -16@⊥) (Push 0@) (Store*AB))]
(define w0 (verify-EENI* init halted? mem≈ p0 #f))
(check-type w0 : Witness)
(check-type (EENI-witness? w0) : Bool -> #t)
;; (define (valid-case name ended? prog [k #f])
;; (test-case name (check-true (verify-EENI* init ended? mem≈ prog k))))
;; (define-syntax-rule (define-tests id desc expr ...)
;; (define id
;; (test-suite+
;; desc
;; (begin expr ...))))
;; ; Checks for counterexamples for bugs in basic semantics.
;; (define-tests basic-bugs "IFC: counterexamples for bugs in basic semantics"
;; (cex-case "Fig. 1" halted? (program 3 (list Halt Noop Push Pop Add* Load* Store*AB)))
;; (cex-case "Fig. 2" halted? (program 3 (list Halt Noop Push Pop Add* Load* Store*B)))
;; (cex-case "Fig. 3" halted? (program 5 (list Halt Noop Push Pop Add* Load* Store)))
;; (cex-case "Fig. 4" halted? (program 7 (list Halt Noop Push Pop Add Load* Store))))
;; (define-tests basic-correct "IFC: no bounded counterexamples for correct basic semantics"
;; (valid-case "*" halted? (program 7 (list Halt Noop Push Pop Add Load Store)))
;; (valid-case "+" halted? (program 8 (list Halt Noop Push Pop Add Load Store))))
;; (define-tests jump-bugs "IFC: counterexamples for bugs in jump+basic semantics"
;; (cex-case "11" halted? (program 6 (list Halt Noop Push Pop Add Load Store Jump*AB)))
;; (cex-case "12" halted? (program 4 (list Halt Noop Push Pop Add Load Store Jump*B))))
;; (define-tests jump-correct "IFC: no bounded counterexamples for correct jump+basic semantics"
;; (valid-case "**" halted? (program 7 (list Halt Noop Push Pop Add Load Store Jump)))
;; (valid-case "++" halted? (program 8 (list Halt Noop Push Pop Add Load Store Jump))))
;; (define-tests call-return-bugs "IFC: counterexamples for buggy call+return+basic semantics"
;; (cex-case "Fig. 13" halted∩low? (program 7 (list Halt Noop Push Pop Add Load Store Call*B Return*AB)))
;; (cex-case "Fig. 15" halted∩low? (program 8 (list Halt Noop Push Pop Add Load StoreCR Call*B Return*AB)))
;; (cex-case "Fig. 16" halted∩low? (program 8 (list Halt Noop Push Pop Add Load StoreCR Call*B Return*B)))
;; (cex-case "Fig. 17" halted∩low? (program 10 (list Halt Noop Push Pop Add Load StoreCR Call Return))))
;; (define-tests reproduce-bugs "IFC: counterexamples that are structurally similar to those in prior work"
;; (cex-case "Fig. 13*" halted∩low? (program (list Push Call*B Halt Push Push Store Return*AB)))
;; (cex-case "Fig. 15*" halted∩low? (program (list Push Push Call*B Push StoreCR Halt Push Return*AB)))
;; (cex-case "Fig. 16*" halted∩low? (program (list Push Push Call*B Push StoreCR Halt Return*B Push Return*B)))
;; (cex-case "Fig. 17*"
;; halted∩low?
;; (program (list Push Call Push StoreCR Halt Push Push Call Pop Push Return))
;; 13))
;; (define (fast-tests)
;; (time (run-tests basic-bugs)) ; ~10 sec
;; (time (run-tests basic-correct)) ; ~20 sec
;; (time (run-tests jump-bugs))) ; ~7 sec
;; (define (slow-tests)
;; (time (run-tests jump-correct)) ; ~52 sec
;; (time (run-tests call-return-bugs)) ; ~440 sec
;; (time (run-tests reproduce-bugs))) ; ~256 sec
;; (module+ fast
;; (fast-tests))
;; (module+ test
;; (fast-tests)
;; (slow-tests))

View File

@ -0,0 +1,251 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt"
"check-type+asserts.rkt")
;; all examples from the Rosette Guide, Sec 2
(define-symbolic b boolean?)
(check-type b : Bool)
(check-type (boolean? b) : Bool -> #t)
(check-type (integer? b) : Bool -> #f)
;; TODO: fix these tests?
(check-type (vector b 1) : (CMVectorof (U (Constant Bool) CPosInt)) -> (vector b 1))
;; mut vectors are invariant
(check-not-type (vector b 1) : (CMVectorof (U Bool CPosInt)))
(check-not-type (vector b 1) : (CIVectorof (U Bool CPosInt)))
(check-not-type (vector b 1) : (CMVectorof (CU CBool CPosInt)))
(check-type (vector b 1) : (CMVectorof (U (Constant Bool) CPosInt)))
;; mutable vectors are invariant
(check-not-type (vector b 1) : (CMVectorof (U CBool CPosInt)))
(check-not-type (vector b 1) : (CMVectorof (U Bool CInt)))
(check-type (vector b 1) : (CVectorof (U (Constant Bool) PosInt)))
;; vectors are also invariant, because it includes mvectors
(check-not-type (vector b 1) : (CVectorof (U Bool PosInt)))
(check-not-type (vector b 1) : (CVectorof (U Bool CInt)))
(check-not-type (vector b 1) : (CVectorof (U Bool Int)))
(check-type (not b) : Bool -> (! b))
(check-type (boolean? (not b)) : Bool -> #t)
(define-symbolic* n integer?)
;; TODO: support internal definition contexts
(define (static -> Bool)
(let-symbolic (x boolean?) x))
#;(define (static -> Bool)
(define-symbolic x boolean? : Bool) ; creates the same constant when evaluated
x)
(define (dynamic -> Int)
(let-symbolic* (y integer?) y))
#;(define (dynamic -> Int)
(define-symbolic* y integer? : Int) ; creates a different constant when evaluated
y)
(check-type static : (C→ Bool))
(check-not-type static : (C→ CBool))
(check-type dynamic : (C→ Int))
(check-type dynamic : (C→ Num))
(check-not-type dynamic : (C→ CInt))
(check-type (eq? (static) (static)) : Bool -> #t)
(define sym*1 (dynamic))
(define sym*2 (dynamic))
(check-type (eq? sym*1 sym*2) : Bool -> (= sym*1 sym*2))
(define (yet-another-x -> Bool)
(let-symbolic (x boolean?) x))
(check-type (eq? (static) (yet-another-x))
: Bool -> (<=> (static) (yet-another-x)))
(check-type+asserts (assert #t) : Unit -> (void) (list))
(check-runtime-exn (assert #f))
(check-type+asserts (assert (not b)) : Unit -> (void) (list (! b) #f))
(check-type (clear-asserts!) : Unit -> (void))
(check-type (asserts) : (CListof Bool) -> (list))
;; sec 2.3
(define (poly [x : Int] -> Int)
(+ (* x x x x) (* 6 x x x) (* 11 x x) (* 6 x)))
(define (factored [x : Int] -> Int)
(* x (+ x 1) (+ x 2) (+ x 2)))
(define (same [p : (C→ Int Int)] [f : (C→ Int Int)] [x : Int] -> Unit)
(assert (= (p x) (f x))))
; check zeros; all seems well ...
(check-type+asserts (same poly factored 0) : Unit -> (void) (list))
(check-type+asserts (same poly factored -1) : Unit -> (void) (list))
(check-type+asserts (same poly factored -2) : Unit -> (void) (list))
;; 2.3.1 Verification
(define-symbolic i integer?)
(define cex (verify (same poly factored i)))
(check-type cex : CSolution)
(check-type (sat? cex) : Bool -> #t)
(check-type (unsat? cex) : Bool -> #f)
(check-type (evaluate i cex) : Int -> 12)
(check-runtime-exn (same poly factored 12))
(clear-asserts!)
;; 2.3.2 Debugging
(require "../../../rosette/query/debug3.rkt"
"../../../rosette/lib/render3.rkt")
(define/debug (factored/d [x : Int] -> Int)
(* x (+ x 1) (+ x 2) (+ x 2)))
(define ucore (debug [integer?] (same poly factored/d 12)))
(typecheck-fail (debug [positive?] (same poly factored/d 12))
#:with-msg "Expected a Rosette-solvable type, given.*positive?")
(typecheck-fail (debug [(~> integer? integer?)] (same poly factored/d 12))
#:with-msg "Expected a non-function Rosette type, given.*~> integer\\? integer\\?")
(check-type ucore : CSolution)
;; TESTING TODO: requires visual inspection (in DrRacket)
(check-type (render ucore) : CPict)
;; 2.3.3 Synthesis
(require "../../../rosette/lib/synthax3.rkt")
(check-type (??) : Int)
(check-type (?? boolean?) : Bool)
(typecheck-fail (?? positive?)
#:with-msg "Expected a Rosette-solvable type, given.*positive?")
(typecheck-fail (?? (~> integer? integer?))
#:with-msg "Expected a non-function Rosette type, given.*integer\\? integer\\?")
(define (factored/?? [x : Int] -> Int)
(* (+ x (??)) (+ x 1) (+ x (??)) (+ x (??))))
(define binding
(synthesize #:forall (list i)
#:guarantee (same poly factored/?? i)))
(check-type binding : CSolution)
(check-type (sat? binding) : Bool -> #t)
(check-type (unsat? binding) : Bool -> #f)
;; TESTING TODO: requires visual inspection of stdout
(check-type (print-forms binding) : Unit -> (void))
;; typed/rosette should print:
;; '(define (factored/?? (x : Int) -> Int) (* (+ x 3) (+ x 1) (+ x 2) (+ x 0)))
;; (untyped) rosette should print:
;; '(define (factored x) (* (+ x 3) (+ x 1) (+ x 2) (+ x 0)))
;; 2.3.4 Angelic Execution
(define-symbolic x y integer?)
(define sol
(solve (begin (assert (not (= x y)))
(assert (< (abs x) 10))
(assert (< (abs y) 10))
(assert (not (= (poly x) 0)))
(assert (= (poly x) (poly y))))))
(check-type sol : CSolution)
(check-type (sat? sol) : Bool -> #t)
(check-type (unsat? sol) : Bool -> #f)
(check-type (evaluate x sol) : Int -> -5)
(check-type (evaluate y sol) : Int -> 2)
(check-type (evaluate (poly x) sol) : Int -> 120)
(check-type (evaluate (poly y) sol) : Int -> 120)
;; 2.4 Symbolic Reasoning
(define-symbolic x1 y1 real?)
(check-type (current-bitwidth) : (CU CPosInt CFalse) -> 5)
(check-type (current-bitwidth #f) : CUnit -> (void))
(check-type (current-bitwidth) : (CU CPosInt CFalse) -> #f)
(check-not-type (current-bitwidth) : CFalse)
(typecheck-fail (current-bitwidth #t) #:with-msg "expected \\(CU CFalse CPosInt\\), given True")
(typecheck-fail (current-bitwidth 0) #:with-msg "expected \\(CU CFalse CPosInt\\), given Zero")
(typecheck-fail (current-bitwidth -1) #:with-msg "expected \\(CU CFalse CPosInt\\), given NegInt")
(check-type (current-bitwidth 5) : CUnit -> (void))
; there is no solution under 5-bit signed integer semantics
(check-type (solve (assert (= x1 3.5))) : CSolution -> (unsat))
(check-type (solve (assert (= x1 64))) : CSolution -> (unsat))
; and quantifiers are not supported
(check-runtime-exn (solve (assert (forall (list x1) (= x1 (+ x1 y1))))))
;; expected err:
;; finitize: cannot use (current-bitwidth 5) with a quantified formula
;; (forall (x1) (= x1 (+ x1 y1))); use (current-bitwidth #f) instead
;; infinite precision semantics
(current-bitwidth #f)
(define sol1 (solve (assert (= x1 3.5))))
;; sol1 = (model [x1 7/2])
(check-type sol1 : CSolution)
(check-type (sat? sol1) : Bool -> #t)
(check-type (evaluate x1 sol1) : Num -> 7/2)
(define sol2 (solve (assert (= x1 64))))
;; sol2 = (model [x1 64.0])
(check-type sol2 : CSolution)
(check-type (sat? sol2) : Bool -> #t)
(check-type (evaluate x1 sol2) : Num -> 64.0)
;; and quantifiers work
(define sol3 (solve (assert (forall (list x1) (= x1 (+ x1 y1))))))
;; sol3 = (model [y1 0.0])
(check-type sol3 : CSolution)
(check-type (sat? sol3) : Bool -> #t)
(check-type (evaluate y1 sol3) : Num -> 0.0)
;; these examples uses symbolic lists
(check-type
(letrec ([[ones : (C→ Int (Listof Int))]
(lambda ([n : Int])
(if (<= n 0)
(list)
(cons 1 (ones (- n 1)))))])
(printf "~a" (ones 3))
(printf "~a" (ones x)))
: Unit)
(check-type
(letrec ([[ones : (C→ Int (Listof Int))]
(lambda ([n : Int])
(if (<= n 0)
(list)
(cons 1 (ones (- n 1)))))])
(ones 3))
: (Listof Int) -> (list 1 1 1))
;; inf loop
(check-type
(letrec ([[ones : (C→ Int (Listof Int))]
(lambda ([n : Int])
(if (<= n 0)
(list)
(cons 1 (ones (- n 1)))))])
(ones x))
: (Listof Int))
;; drop lambda annotation
(check-type
(letrec ([[ones : (C→ Int (Listof Int))]
(lambda (n)
(if (<= n 0)
(list)
(cons 1 (ones (- n 1)))))])
(printf "~a" (ones 3))
(printf "~a" (ones x)))
: Unit)
(check-type
(letrec ([[adder : (C→ (CListof Int) Int (CListof Int))]
(lambda (vs n)
(if (null? vs)
(list)
(cons (+ (car vs) n) (adder (cdr vs) n))))])
(adder '(1 2 3) x))
: (CListof Int) -> (list (+ 1 x) (+ 2 x) (+ 3 x)))

View File

@ -0,0 +1,120 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt"
"check-type+asserts.rkt")
;; Examples from the Rosette Guide, Section 3
;; Symbolic effects
(define y1 (ann 0 : Nat))
(check-type (if #t (void) (set! y1 3)) : CUnit -> (void))
;; y1 unchanged: 0
(check-type y1 : Nat -> 0)
(check-type (if #f (set! y1 3) (void)) : CUnit -> (void))
;; y1 unchanged: 0
(check-type y1 : Nat -> 0)
;; symbolic effect!
(define-symbolic x1 boolean?)
(typecheck-fail (define-symbolic x1 boolean? : Bool))
(check-type (if x1 (void) (set! y1 3)) : Unit -> (void))
;; y1 symbolic: (ite x1 0 3)
(check-type y1 : Nat -> (if x1 0 3))
(define res
(let ([y (ann 0 : Nat)])
(if #t (void) (set! y 3))
(printf "y unchanged: ~a\n" y)
(if #f (set! y 3) (void))
(printf "y unchanged: ~a\n" y)
(let-symbolic (x boolean?)
(if x (void) (set! y 3))
(printf "y symbolic: ~a\n" y)
(list x y))))
(check-type res : (CList Bool Nat))
(check-type (second res) : Nat -> (if (first res) 0 3))
;; use car and cdr instead
(check-type (car (cdr res)) : Nat -> (if (car res) 0 3))
;; 3.2 Solver-Aided Forms
;; 3.2.1 Symbolic Constants
(define (always-same -> Int)
(let-symbolic (x integer?)
x))
(check-type (always-same) : Int)
(check-type (eq? (always-same) (always-same)) : Bool -> #t)
(define (always-different -> Int)
(let-symbolic* (x integer?)
x))
(check-type (always-different) : Int)
(define diff-sym*1 (always-different))
(define diff-sym*2 (always-different))
(check-type (eq? diff-sym*1 diff-sym*2) : Bool -> (= diff-sym*1 diff-sym*2))
;; 3.2.2 Assertions
(check-type+asserts (assert #t) : Unit -> (void) (list))
(check-type+asserts (assert 1) : Unit -> (void) (list))
(define-symbolic x123 boolean?)
(check-type+asserts (assert x123) : Unit -> (void) (list x123))
(check-runtime-exn (assert #f "bad value"))
(check-type (asserts) : (CListof Bool) -> (list #f))
(check-type (clear-asserts!) : Unit -> (void))
(check-type (asserts) : (CListof Bool) -> (list))
;; 3.2.3 Angelic Execution
(define-symbolic x y boolean?)
(check-type (assert x) : Unit -> (void))
(check-type (asserts) : (CListof Bool) -> (list x))
(define solve-sol (solve (assert y)))
(check-type solve-sol : CSolution)
(check-type (sat? solve-sol) : Bool -> #t)
(check-type (evaluate x solve-sol) : Bool -> #t) ; x must be true
(check-type (evaluate y solve-sol) : Bool -> #t) ; y must be true
(check-type (solve (assert (not x))) : CSolution -> (unsat))
(clear-asserts!)
;; 3.2.4 Verification
(check-type (assert x) : Unit -> (void))
(check-type (asserts) : (CListof Bool) -> (list x))
(define verif-sol (verify (assert y)))
(check-type (asserts) : (CListof Bool) -> (list x))
(check-type (evaluate x verif-sol) : Bool -> #t) ; x must be true
(check-type (evaluate y verif-sol) : Bool -> #f) ; y must be false
(check-type (verify #:assume (assert y) #:guarantee (assert (and x y)))
: CSolution -> (unsat))
(clear-asserts!)
;; 3.2.5 Synthesis
(define-symbolic synth-x synth-c integer?)
(check-type (assert (even? synth-x)) : Unit -> (void))
(check-type (asserts) : (CListof Bool) -> (list (= 0 (remainder synth-x 2))))
(define synth-sol
(synthesize #:forall (list synth-x)
#:guarantee (assert (odd? (+ synth-x synth-c)))))
(check-type (asserts) : (CListof Bool) -> (list (= 0 (remainder synth-x 2))))
(check-type (evaluate synth-x synth-sol) : Int -> synth-x) ; x is unbound
(check-type (evaluate synth-c synth-sol) : Int -> 1) ; c must an odd integer
(clear-asserts!)
;; 3.2.6 Optimization
(current-bitwidth #f) ; use infinite-precision arithmetic
(define-symbolic opt-x opt-y integer?)
(check-type (assert (< opt-x 2)) : Unit -> (void))
(check-type (asserts) : (CListof Bool) -> (list (< opt-x 2)))
(define opt-sol
(optimize #:maximize (list (+ opt-x opt-y))
#:guarantee (assert (< (- opt-y opt-x) 1))))
; assertion store same as before
(check-type (asserts) : (CListof Bool) -> (list (< opt-x 2)))
; x + y is maximal at x = 1 and y = 1
(check-type (evaluate opt-x opt-sol) : Int -> 1)
(check-type (evaluate opt-y opt-sol) : Int -> 1)
;; 3.2.8 Reasoning Precision
;; see rosette-guide-sec2-tests.rkt, Sec 2.4 Symbolic Reasoning

View File

@ -0,0 +1,259 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt")
;; Examples from the Rosette Guide, Section 4.1 - 4.2
;; 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?)
(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)
(typecheck-fail (~> positive? positive?)
#:with-msg "Expected a Rosette\\-solvable type, given.*positive?")
(typecheck-fail (~> (~> integer? integer?) integer?)
#:with-msg "Expected a non\\-function Rosette type, given.*~> integer?")
(define-symbolic f g (~> integer? integer?))
(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?)
(check-type (distinct? 3 z x y 2) : Bool -> (distinct? 2 3 x y z))
(define-symbolic b boolean?)
(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?)
(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?)
; 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?)
(check-type (forall (list) (= a1 b1)) : Bool -> (= a1 b1))
(define f1 (forall (list a1) (exists (list b1) (= a1 (+ a1 b1))))) ; no free constants
(check-type (list 1) : (CListof PosInt))
(check-type (list 1) : (CList PosInt))
(typecheck-fail (exists (list 1) (= a1 b1))
#:with-msg "Expected list of symbolic constants, given list containing: PosInt")
(typecheck-fail (exists (list (+ a1 b1)) (= a1 b1))
#:with-msg "Expected list of symbolic constants, given list containing: Int")
(check-type (cons a1 (cons b (list))) : (CList (Constant Int) (Constant Bool)))
(typecheck-fail (forall (list 1) (= a1 b1))
#:with-msg "Expected list of symbolic constants, given list containing: PosInt")
(typecheck-fail (forall (list (+ a1 b1)) (= a1 b1))
#:with-msg "Expected list of symbolic constants, given list containing: Int")
; so the model has no bindings
(define sol1 (solve (assert f1)))
(check-type sol1 : CSolution)
(check-type (model sol1) : (CHashTable Any Any))
(check-type (hash-keys (model sol1)) : (CListof Any) -> (list)) ; empty solution
(check-type (sat? sol1) : Bool -> #t)
(define g1 (forall (list a1) (= a1 (+ a1 b1)))) ; b1 is free in g1
; 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)
; body refers to the innermost a1
(define h (exists (list a1) (forall (list a1) (= a1 (+ a1 a1)))))
; so h is unsatisfiable.
(check-type (solve (assert h)) : CSolution -> (unsat))

View File

@ -0,0 +1,190 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt")
;; Examples from the Rosette Guide, Section 4.3
;; 4.3 Bitvectors
; a bitvector literal of size 7
(check-type (bv 4 (bitvector 7)) : BV -> (bv 4 7))
(check-type (bv 4 7) : BV -> (bv 4 7))
(define-symbolic x y (bitvector 7)) ; symbolic bitvector constants
(check-type x : BV)
(check-type y : BV)
(check-type (bvslt (bv 4 7) (bv -1 7)) : Bool -> #f)
; unsigned 7-bit < comparison of 4 and -1
(check-type (bvult (bv 4 7) (bv -1 7)) : Bool -> #t)
(define-symbolic b boolean?)
; this typechecks only when b is true
(check-type (bvadd x (if b y (bv 3 4))) : BV -> (bvadd x y))
(check-type (asserts) : (CListof Bool) -> (list b)) ; Rosette emits an appropriate assertion
(clear-asserts!)
;; bitvector
(define bv6? (bitvector 6))
(check-type (bv6? 1) : Bool -> #f)
(check-type (bv6? (bv 3 6)) : Bool -> #t)
(check-type (bv6? (bv 3 5)) : Bool -> #f)
;(define-symbolic b boolean?)
(check-type (bv6? (if b (bv 3 6) #t)) : Bool -> b)
(check-not-type (bv6? (if b (bv 3 6) #t)) : CBool)
;; bitvector?
;(define bv6? (bitvector 6))
(define bv7? (bitvector 7))
;(define-symbolic b boolean?)
(check-type (bitvector? bv6?) : Bool -> #t) ; a concrete bitvector type
(check-type (bitvector? (if b bv6? bv7?)) : Bool -> #f) ; not a concrete type
(check-type (bitvector? integer?) : Bool -> #f) ; not a bitvector type
(check-type (bitvector? 3) : Bool -> #f) ; not a type
;; result is always CBool
(check-type (bitvector? bv6?) : CBool -> #t) ; a concrete bitvector type
(check-type (bitvector? (if b bv6? bv7?)) : CBool -> #f) ; not a concrete type
(check-type (bitvector? integer?) : CBool -> #f) ; not a bitvector type
(check-type (bitvector? 3) : CBool -> #f) ; not a type
;; check CFalse when possible
(check-not-type (bitvector? bv6?) : CFalse) ; a concrete bitvector type
(check-type (bitvector? (if b bv6? bv7?)) : CFalse -> #f) ; not a concrete type
(check-not-type (bitvector? integer?) : CFalse) ; not a bitvector type
(check-type (bitvector? 3) : CFalse -> #f) ; not a type
;; bv?
(check-type (bv? 1) : Bool -> #f)
(check-type (bv? (bv 1 1)) : Bool -> #t)
(check-type (bv? (bv 2 2)) : Bool -> #t)
;define-symbolic b boolean?)
(check-type (bv? (if b (bv 3 6) #t)) : Bool -> b)
;; 4.3.1 Comparison Ops
(define-symbolic u v (bitvector 7)) ; symbolic bitvector constants
(check-type (bvslt (bv 4 7) (bv -1 7)) : Bool -> #f) ; signed 7-bit < of 4 and -1
(check-type (bvult (bv 4 7) (bv -1 7)) : Bool -> #t) ; unsigned 7-bit < of 4 and -1
;(define-symbolic b boolean?)
(check-type (bvsge u (if b v (bv 3 4))) : Bool -> (bvsle v u)) ; b must be true, else err
(check-type (asserts) : (CListof Bool) -> (list b)) ; so Rosette emits assertion
(clear-asserts!)
;; 4.3.2 Bitwise Ops
(check-type (bvnot (bv -1 4)) : BV -> (bv 0 4))
(check-type (bvnot (bv 0 4)) : BV -> (bv -1 4))
;(define-symbolic b boolean?)
;; typed Rosette rejects this program
(typecheck-fail (bvnot (if b 0 (bv 0 4)))
#:with-msg "expected BV, given \\(U Zero CBV\\)")
;; need assert-type annotation
(check-type (bvnot (assert-type (if b 0 (bv 0 4)) : BV)) : BV -> (bv -1 4))
(check-type (asserts) : (CListof Bool) -> (list (! b)))
(clear-asserts!)
(check-type (bvand (bv -1 4) (bv 2 4)) : BV -> (bv 2 4))
(check-type (bvor (bv 0 3) (bv 1 3)) : BV -> (bv 1 3))
(check-type (bvxor (bv -1 5) (bv 1 5)) : BV -> (bv -2 5))
;(define-symbolic b boolean?)
;; typed Rosette rejects this program
(typecheck-fail (bvand (bv -1 4) (if b 0 (bv 2 4)))
#:with-msg "expected BV, given \\(U Zero CBV\\)")
;; need assert-type annotation
(check-type (bvand (bv -1 4) (assert-type (if b 0 (bv 2 4)) : BV)) : BV -> (bv 2 4))
(check-type (asserts) : (CListof Bool) -> (list (! b)))
(clear-asserts!)
(check-type (bvshl (bv 1 4) (bv 2 4)) : BV -> (bv 4 4))
(check-type (bvlshr (bv -1 3) (bv 1 3)) : BV -> (bv 3 3))
(check-type (bvashr (bv -1 5) (bv 1 5)) : BV -> (bv -1 5))
;(define-symbolic b boolean?)
;; typed Rosette rejects this program
(typecheck-fail (bvshl (bv -1 4) (if b 0 (bv 2 4)))
#:with-msg "expected BV, given \\(U Zero CBV\\)")
;; need assert-type annotation
(check-type (bvshl (bv -1 4) (assert-type (if b 0 (bv 2 4)) : BV)) : BV -> (bv -4 4))
(check-type (asserts) : CAsserts -> (list (! b)))
(clear-asserts!)
;; 4.3.3 Arithmetic Ops
(check-type (bvneg (bv -1 4)) : BV -> (bv 1 4))
(check-type (bvneg (bv 0 4)) : BV -> (bv 0 4))
(define-symbolic z (bitvector 3))
(check-type (bvneg z) : BV -> (bvneg z))
(check-type (bvadd (bv -1 4) (bv 2 4)) : BV -> (bv 1 4))
(check-type (bvsub (bv 0 3) (bv 1 3)) : BV -> (bv -1 3))
(check-type (bvmul (bv -1 5) (bv 1 5)) : BV -> (bv -1 5))
;> (define-symbolic b boolean?)
;; typed Rosette rejects this program
(typecheck-fail (bvadd (bv -1 4) (bv 2 4) (if b (bv 1 4) "bad"))
#:with-msg "expected.*BV.*given.*\\(U CBV String\\)")
;; need assert-type annotation
(check-type (bvadd (bv -1 4) (bv 2 4) (assert-type (if b (bv 1 4) "bad") : BV))
: BV -> (bv 2 4))
(check-type (asserts) : CAsserts -> (list b))
(clear-asserts!)
(check-type (bvsdiv (bv -3 4) (bv 2 4)) : BV -> (bv -1 4))
(check-type (bvudiv (bv -3 3) (bv 2 3)) : BV -> (bv 2 3))
(check-type (bvsmod (bv 1 5) (bv 0 5)) : BV -> (bv 1 5))
;> (define-symbolic b boolean?)
;; typed Rosette rejects this program
(typecheck-fail (bvsrem (bv -3 4) (if b (bv 2 4) "bad"))
#:with-msg "expected.*BV.*given.*\\(U CBV String\\)")
;; need assert-type annotation
(check-type (bvsrem (bv -3 4) (assert-type (if b (bv 2 4) "bad") : BV))
: BV -> (bv -1 4))
(check-type (asserts) : CAsserts -> (list b))
(clear-asserts!)
;; 4.3.4 Conversion Ops
(check-type (concat (bv -1 4) (bv 0 1) (bv -1 3)) : BV -> (bv -9 8))
;> (define-symbolic b boolean?)
(check-type (concat (bv -1 4) (if b (bv 0 1) (bv 0 2)) (bv -1 3))
: BV); -> {[b (bv -9 8)] [(! b) (bv -25 9)]})
(check-type (extract 2 1 (bv -1 4)) : BV -> (bv -1 2))
(check-type (extract 3 3 (bv 1 4)) : BV -> (bv 0 1))
(define-symbolic i j integer?)
(check-type (extract i j (bv 1 2)) : BV -> (extract i j (bv 1 2)))
; -> {[(&& (= 0 j) (= 1 i)) (bv 1 2)] ...}
(check-type (asserts) : CAsserts -> (list (< i 2) (<= 0 j) (<= j i)))
(clear-asserts!)
(check-type (sign-extend (bv -3 4) (bitvector 6)) : BV -> (bv -3 6))
(check-type (zero-extend (bv -3 4) (bitvector 6)) : BV -> (bv 13 6))
(define-symbolic c boolean?)
(check-type (zero-extend (bv -3 4) (if b (bitvector 5) (bitvector 6)))
: BV -> (zero-extend (bv -3 4) (if b (bitvector 5) (bitvector 6))))
; {[b (bv 13 5)] [(! b) (bv 13 6)]})
;; typed Rosette rejects this program
(typecheck-fail (zero-extend (bv -3 4) (if b (bitvector 5) "bad"))
#:with-msg "expected.*BVPred.*given.*\\(U CBVPred String\\)")
;; need assert-type annotation
(check-type (zero-extend (bv -3 4) (assert-type (if b (bitvector 5) "bad") : BVPred))
: BV -> (bv 13 5))
(check-type (asserts) : CAsserts -> (list b))
(check-type (zero-extend (bv -3 4) (if c (bitvector 5) (bitvector 1))) : BV -> (bv 13 5))
(check-type (asserts) : CAsserts -> (list c b))
(clear-asserts!)
(check-type (bitvector->integer (bv -1 4)) : Int -> -1)
(check-type (bitvector->natural (bv -1 4)) : Nat -> 15)
;> (define-symbolic b boolean?)
(check-type (bitvector->integer (if b (bv -1 3) (bv -3 4))) : Int -> (if b -1 -3))
;; typed Rosette rejects this program
(typecheck-fail (bitvector->integer (if b (bv -1 3) "bad"))
#:with-msg "expected.*BV.*given.*\\(U CBV String\\)")
;; need assert-type annotation
(check-type (bitvector->integer (assert-type (if b (bv -1 3) "bad") : BV)) : Int -> -1)
(check-type (asserts) : CAsserts -> (list b))
(clear-asserts!)
(check-type (integer->bitvector 4 (bitvector 2)) : BV -> (bv 0 2))
(check-type (integer->bitvector 15 (bitvector 4)) : BV -> (bv -1 4))
;> (define-symbolic b c boolean?)
;; typed Rosette rejects this program
(typecheck-fail (integer->bitvector (if b pi 3) (if c (bitvector 5) (bitvector 6)))
#:with-msg "expected Int, given.*Num")
(check-type (if b pi 3) : Num)
(check-not-type (if b pi 3) : Int)
;; need assert-type annotation
(define res (integer->bitvector (assert-type (if b pi 3) : Int)
(if c (bitvector 5) (bitvector 6))))
(check-type res : BV) ;{[c (bv 3 5)] [(! c) (bv 3 6)]})
(check-type (asserts) : CAsserts -> (list (! b)))

View File

@ -0,0 +1,114 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt")
;; Examples from the Rosette Guide, Section 4.4
;; 4.4 Uninterpreted Functions
;; example demonstrating unsoundness of Constant
;; (define-symbolic f (~> integer? boolean?))
;; (define-symbolic x integer?)
;; (define sol (solve (assert (not (equal? (f x) (f 1))))))
;; (define res (evaluate x sol))
;; (check-type res : (Constant Int))
;; (constant? res)
; an uninterpreted function from integers to booleans:
(define-symbolic f (~> integer? boolean?))
; no built-in interpretation for 1
(check-type (f 1) : Bool -> (f 1))
(check-not-type (f 1) : CBool)
(define-symbolic x real?)
; typed Rosette rejects tis program
(typecheck-fail (f x) #:with-msg "expected Int, given.*Num")
;; must use assert-type to cast to Int
(check-type (f (assert-type x : Int))
: Bool -> (f (assert-type x : Int))) ;(app f (real->integer x)))
(check-type (asserts) : CAsserts -> (list (integer? x)))
(clear-asserts!)
;(clear-terms!) ; must not clear terms
;; typed Rosette rejects this program
(typecheck-fail (solve (assert (not (equal? (f x) (f 1)))))
#:with-msg "expected Int, given.*Num")
;; must use assert-type to cast x toInt
(define sol (solve (assert (not (equal? (f (assert-type x : Int)) (f 1))))))
(check-type sol : CSolution)
(define g (evaluate f sol)) ; an interpretation of f
(check-type g : ( Int Bool)) ; -> (fv (((1) . #f) ((0) . #t)) #f integer?~>boolean?)
; f is a function value
(check-type (fv? f) : Bool -> #t)
; and so is g
(check-type (fv? g) : Bool -> #t)
;; The tests below depend on a specific term-cache (should be commented out above)
;; at the time solve was called
;; should this be Num or Int?
;(check-type (evaluate x sol) : Int -> 0)
(check-type (evaluate x sol) : Num -> 0)
;; check soundness of Constant
(check-not-type (evaluate x sol) : (Constant Num))
; we can apply g to concrete values
(check-type (g 2) : Bool -> #f)
; and to symbolic values
(check-type (g (assert-type x : Int)) : Bool -> (= 0 (real->integer x)))
;; this test does not depend on the term cache
(check-type (equal? (g 1) (g (assert-type (evaluate x sol) : Int))) : Bool -> #f)
(clear-asserts!)
;; ~>
(define t (~> integer? real? boolean? (bitvector 4)))
(check-type t : (C→ Any Bool) -> (~> integer? real? boolean? (bitvector 4))) ;integer?~>real?~>boolean?~>(bitvector? 4)
(typecheck-fail (~> t integer?)
#:with-msg "Expected a non-function Rosette type, given.*t")
(define-symbolic b boolean?)
(typecheck-fail (~> integer? (if b boolean? real?))
#:with-msg "Expected a Rosette-solvable type, given")
(typecheck-fail (~> real?) #:with-msg "expected more terms")
;; function?
(define t0? (~> integer? real? boolean? (bitvector 4)))
(define t1? (~> integer? real?))
(check-type (function? t0?) : Bool -> #t)
(check-type (function? t1?) : Bool -> #t)
;> (define-symbolic b boolean?)
(check-type (function? (if b t0? t1?)) : Bool -> #f) ; not a concrete type
(check-type (function? integer?) : Bool -> #f) ; not a function type
(check-type (function? 3) : Bool -> #f) ; not a type
;; should always be CBool, and sometimes CFalse
(check-type (function? t0?) : CBool -> #t)
(check-type (function? t1?) : CBool -> #t)
(check-type (function? (if b t0? t1?)) : CBool -> #f) ; not a concrete type
(check-type (function? integer?) : CBool -> #f) ; not a function type
(check-type (function? 3) : CBool -> #f) ; not a type
(check-type (function? t0?) : CBool -> #t)
(check-type (function? t1?) : CBool -> #t)
(check-type (function? (if b t0? t1?)) : CFalse -> #f) ; not a concrete type
(check-type (function? integer?) : CBool -> #f) ; not a function type
(check-type (function? 3) : CFalse -> #f) ; not a type
;; fv?
(define-symbolic f2 (~> boolean? boolean?))
(check-type (fv? f2) : Bool -> #t)
(check-not-type (fv? f2) : CBool)
(check-type (fv? (lambda ([x : Int]) x)) : Bool -> #f)
;> (define-symbolic b boolean?)
(check-type (fv? (if b f2 1)) : Bool -> b)
(define sol2
(solve
(begin
(assert (not (f2 #t)))
(assert (f2 #f)))))
(check-type sol2 : CSolution)
(check-type (sat? sol2) : Bool -> #t)
(define g2 (evaluate f2 sol2))
(check-type g2 : ( Bool Bool)) ; g2 implements logical negation
;(fv (((#f) . #t) ((#t) . #f)) #t boolean?~>boolean?)
(check-type (fv? g2) : Bool -> #t)
; verify that g implements logical negation:
(check-type (verify (assert (equal? (g2 b) (not b)))) : CSolution -> (unsat))
(check-type (g2 #t) : Bool -> #f)
(check-type (g2 #f) : Bool -> #t)

View File

@ -0,0 +1,21 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt")
;; Examples from the Rosette Guide, Section 4.5
;; 4.5 Procedures
(define-symbolic b boolean?)
(define-symbolic x integer?)
(define p (if b * -)) ; p is a symbolic procedure
(check-type p : ( Num Num Num))
(check-not-type p : (C→ Num Num Num)) ; should not have concrete type
(check-type p : ( Int Int Int))
(define sol (synthesize #:forall (list x)
#:guarantee (assert (= x (p x 1)))))
(check-type (evaluate p sol) : ( Int Int Int) -> *)
;; this doesnt hold bc type of result is from p
;(check-type (evaluate p sol) : (→ PosInt PosInt PosInt) -> *)
(define sol2 (synthesize #:forall (list x)
#:guarantee (assert (= x (p x 0)))))
(check-type (evaluate p sol2) : ( Int Int Int) -> -)
(check-not-type (evaluate p sol2) : ( PosInt PosInt PosInt))

View File

@ -0,0 +1,95 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt")
;; Examples from the Rosette Guide, Section 4.6-4.8
;; 4.6 Pairs and Lists
(define-symbolic x y z n integer?)
(define xs (take (list x y z) n)) ; (1) xs is a symbolic list
(check-type xs : (Listof Int))
(define sol1 (solve (assert (null? xs))))
(check-type sol1 : CSolution)
(check-type (sat? sol1) : Bool -> #t)
(check-type (evaluate xs sol1) : (Listof Int) -> '())
(define sol2
(solve (begin
(assert (= (length xs) 2))
(assert (not (equal? xs (reverse xs))))
(assert (equal? xs (sort xs <))))))
(check-type (evaluate xs sol2) : (Listof Int) -> '(1 4))
(define-symbolic b boolean?)
(define p (if b (cons 1 2) (cons 4 #f))) ; (2) p is a symbolic pair
(check-type p : (Pair Nat (U Nat Bool)))
(check-type p : (Pair Any Any))
(check-not-type p : (CPair Any Any)) ; check not concrete
(check-type p : (Pair CNat (CU CNat CBool))) ; contents are concrete
(define sol3 (solve (assert (boolean? (cdr p)))))
(check-type (evaluate p sol3) : (Pair Nat (U Nat Bool)) -> '(4 . #f))
(define sol4 (solve (assert (odd? (car p)))))
(check-type (evaluate p sol4) : (Pair Nat (U Nat Bool)) -> '(1 . 2))
;; 4.7 Vectors
(define v1 (vector 1 2 #f))
(define v2 (vector 1 2 #f))
;; mutable vectors are invariant
(check-type v1 : (CMVectorof (CU CPosInt CFalse)))
(check-type v1 : (CVectorof (CU CPosInt CFalse)))
(check-not-type v1 : (CMVectorof (U Nat Bool)))
(check-not-type v1 : (CVectorof (U Nat Bool)))
(check-type v2 : (CMVectorof (CU CPosInt CFalse)))
(check-type (eq? v1 v2) : Bool -> #f)
(check-type (equal? v1 v2) : Bool -> #t)
(define v3 (vector-immutable 1 2 #f))
(define v4 (vector-immutable 1 2 #f))
;; immutable vectors have supertypes
(check-type v3 : (CIVectorof (CU CPosInt CFalse)))
(check-type v3 : (CVectorof (U Nat Bool)))
(check-type v4 : (CIVectorof (CU CPosInt CFalse)))
(check-type (eq? v3 v4) : Bool -> #t)
(check-type (equal? v1 v3) : Bool -> #t)
;(define-symbolic x y z n integer?)
;(define xs (take (list x y z) n)) ; xs is a symbolic list
(define vs (list->vector xs)) ; vs is a symbolic vector
(check-type vs : (CVectorof (U (Constant Int))))
(check-type vs : (CMVectorof (U (Constant Int))))
(define sol5 (solve (assert (= 4 (vector-ref vs (sub1 n))))))
(check-type (= 4 (vector-ref (evaluate vs sol5) (sub1 (evaluate n sol5))))
: Bool -> #t)
;; TODO: Constant unsound
(check-type (evaluate vs sol5) : (CVectorof Int) -> (vector 0 4))
(check-type (evaluate xs sol5) : (Listof Int) -> '(0 4))
;; 4.8 Boxes
(define b1 (box 1))
(define b2 (box 1))
(check-type b1 : (CMBoxof CPosInt))
(check-type b1 : (CBoxof CPosInt))
(check-not-type b1 : (CMBoxof Nat)) ; invariant
(check-type b2 : (CMBoxof CPosInt))
(check-type (eq? b1 b2) : Bool -> #f)
(check-type (equal? b1 b2) : Bool -> #t)
(define b3 (box-immutable 1))
(define b4 (box-immutable 1))
(check-type b3 : (CIBoxof CPosInt))
(check-type b3 : (CBoxof CPosInt))
(check-type b3 : (CBoxof Nat)) ; subtype ok
(check-type b4 : (CBoxof Nat))
(check-type (eq? b3 b4) : Bool -> #t)
(check-type (equal? b1 b3) : Bool -> #t)
;> (define-symbolic x integer?)
;> (define-symbolic b boolean?)
(define sb1 (box x)) ; sb1 is a box with symbolic contents
(check-type sb1 : (CMBoxof (Constant Int)))
(define sb2 (if b sb1 (box 3))) ; sb2 is a symbolic box
(check-type sb2 : (U (CMBoxof (Constant Int)) (CMBoxof CPosInt)))
(define sol6 (solve (assert (= 4 (unbox sb2)))))
(check-type (evaluate sb1 sol6) : (CMBoxof Int) -> (box 4))
(check-type (evaluate sb2 sol6) : (U (CMBoxof Int) (CMBoxof CPosInt)) -> (box 4))
(check-not-type (evaluate sb2 sol6) : (MBoxof Int))
(check-type (= 4 (unbox (evaluate sb2 sol6))) : Bool -> #t)
(check-type (evaluate (eq? sb1 sb2) sol6) : Bool -> #t)

View File

@ -0,0 +1,32 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt")
;; Examples from the Rosette Guide, Section 4.9 Solvers and Solutions
;; 4.9.1 The Solver Interface
(check-type (current-solver) : CSolver -> (current-solver))
;; TODO
;(check-type gen:solver : CSolver)
;; 4.9.2 Solutions
(define-symbolic a b boolean?)
(define-symbolic x y integer?)
(define sol
(solve (begin (assert a)
(assert (= x 1))
(assert (= y 2)))))
(check-type sol : CSolution)
(check-type (sat? sol) : Bool -> #t)
(check-type (evaluate (list 4 5 x) sol) : (Listof Int) -> '(4 5 1))
(check-type (evaluate (list 4 5 x) sol) : (CListof Int)) ; concrete list ok
(check-not-type (evaluate (list 4 5 x) sol) : (Listof Nat))
(define vec (vector a))
(check-type (evaluate vec sol) : (CMVectorof Bool))
;'#(#t)
; evaluation produces a new vector
(check-type (eq? vec (evaluate vec sol)) : Bool -> #f)
(check-type (evaluate (+ x y) sol) : Int -> 3)
(check-not-type (evaluate (+ x y) sol) : CInt) ; not concrete
(check-type (evaluate (and a b) sol) : Bool -> b)
(check-not-type (evaluate (and a b) sol) : CBool) ; not concrete

View File

@ -0,0 +1,59 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt")
;; Examples from the Rosette Guide, Section 5 Structures
; immutable transparent type
(struct point ([x : Int] [y : Int]) #:transparent)
(check-type point : (C→ Int Int (CPoint Int Int)))
(check-type point-x : (C→ (CPoint Int Int) Int))
(check-type point-y : (C→ (CPoint Int Int) Int))
(check-type point? : (C→ Any Bool))
; opaque immutable type
(struct pt ([x : Int] [y : Int]))
; mutable transparent type
(struct pnt ([x : Int] [y : Int]) #:mutable #:transparent)
(check-type (point 1 2) : (CPoint Int Int) -> (point 1 2))
(typecheck-fail (point #f 2) #:with-msg "expected Int, given False")
(check-type (pt 1 2) : (CPt Int Int)) ; opaque, incomparable
(check-type (pnt 1 2) : (CPnt Int Int) -> (pnt 1 2))
(check-type (eq? (point 1 2) (point 1 2)) : Bool -> #t) ; point structures are values
(check-type (eq? (pt 1 2) (pt 1 2)) : Bool -> #f) ; pt structures are references
(check-type (eq? (pnt 1 2) (pnt 1 2)) : Bool -> #f) ; pnt structures are references
(define-symbolic b boolean?)
(define p (if b (point 1 2) (point 3 4))) ; p holds a symbolic structure
(check-type p : (Point Int Int))
(check-not-type p : (CPoint Int Int))
(check-type (point-x p) : Int -> (if b 1 3)) ;(ite b 1 3)
(check-type (point-y p) : Int -> (if b 2 4)) ;(ite b 2 4)
(define sol (solve (assert (= (point-x p) 3))))
(check-type (evaluate p sol) : (Point Int Int) -> (point 3 4)) ;#(struct:point 3 4)
(check-type (= (point-x (evaluate p sol)) 3) : Bool -> #t)
;; Generics
(define-generics viewable (view viewable -> Nat))
(typecheck-fail
(struct square (side)
#:methods gen:viewable
[(define (view self) (square-side self))])
#:with-msg "Missing type annotations for fields")
(struct square ([side : Nat])
#:methods gen:viewable
[(define (view [self : (Square Nat)] -> Nat) (square-side self))])
(struct circle ([radius : Nat])
#:transparent
#:methods gen:viewable
[(define (view [self : (Circle Nat)] -> Nat) (circle-radius self))])
;(define-symbolic b boolean?)
(define p2 (if b (square 2) (circle 3))) ; p holds a symbolic structure
(check-type p2 : (U (CSquare Nat) (CCircle Nat)))
(check-type p2 : (U (Square Nat) (Circle Nat)))
(check-type (apply-view p2) : Nat -> (if b 2 3)) ;(ite b 2 3)
(define sol2 (solve (assert (= (apply-view p2) 3))))
(check-type (evaluate p2 sol2) : (U (Square Nat) (Circle Nat)) -> (circle 3))
(check-type (= (apply-view (evaluate p2 sol2)) 3) : Bool -> #t)

View File

@ -0,0 +1,52 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt")
;; Examples from the Rosette Guide, Section 6 Libraries
;; 6.2.1 Synthesis library
(require "../../../rosette/lib/synthax3.rkt")
;; choose
(define (div2 [x : BV] -> BV)
([choose bvshl bvashr bvlshr bvadd bvsub bvmul] x (?? (bitvector 8))))
(define-symbolic i (bitvector 8))
(print-forms
(synthesize #:forall (list i)
#:guarantee (assert (equal? (div2 i) (bvudiv i (bv 2 8))))))
(printf "expected output:\n~a\n"
"'(define (div2 [x : BV] -> BV) (bvlshr x (bv 1 8)))")
;; TODO: define-synthax
; Defines a grammar for boolean expressions
; in negation normal form (NNF).
#;(define-synthax (nnf [x : Bool] [y : Bool] [depth : Int] -> Bool)
#:base (choose x (! x) y (! y))
#:else (choose
x (! x) y (! y)
((choose && ||) (nnf x y (- depth 1))
(nnf x y (- depth 1)))))
; The body of nnf=> is a hole to be filled with an
; expression of depth (up to) 1 from the NNF grammar.
#;(define (nnf=> [x : Bool] [y : Bool] -> Bool)
(apply-nnf x y 1))
;; (define-symbolic a b boolean?)
;; (print-forms
;; (synthesize
;; #:forall (list a b)
;; #:guarantee (assert (equal? (=> a b) (nnf=> a b)))))
;; (printf "expected output:\n~a\n"
;; "'(define (nnf=> [x : Bool] [y : Bool] -> Bool) (|| (! x) y))")
;; 6.2.2 Angelic Execution Library
(require "../../../rosette/lib/angelic3.rkt")
(define (static -> Int) (choose 1 2 3))
(define (dynamic -> Int) (choose* 1 2 3))
(check-type (equal? (static) (static)) : Bool -> #t)
(define dyn1 (dynamic))
(define dyn2 (dynamic))
(check-type (equal? dyn1 dyn2) : Bool -> (equal? dyn1 dyn2))
;(= (ite xi?$4 1 (ite xi?$5 2 3)) (ite xi?$6 1 (ite xi?$7 2 3)))

View File

@ -0,0 +1,230 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt")
;; Examples from the Rosette Guide, Section 7 Reflecting on Symbolic Values
;; 7.1.1 Symbolic Terms
(define-symbolic x integer?) ; constant
(define e (+ x 1)) ; expression
(check-type (list (term? x) (term? e)) : (CListof Bool) -> (list #t #t))
(check-type (list (constant? x) (constant? e)) : (CListof Bool) -> (list #t #f))
(check-type (list (expression? x) (expression? e)) : (CListof Bool) -> (list #f #t))
(check-type (term? 1) : Bool -> #f)
;; TODO: match and match expanders
;; > (define-symbolic x integer?) ; constant
;; > (define e (+ x 1)) ; expression
;; > (match x
;; [(constant identifier type) (list identifier type)])
;; '(#<syntax:8:0 x> integer?)
;; > (match x
;; [(term content type) (list content type)])
;; '(#<syntax:8:0 x> integer?)
;; > (match e
;; [(expression op child ...) (cons op child)])
;; '(+ 1 x)
;; > (match e
;; [(term content type) (list content type)])
;; '((+ 1 x) integer?)
;(define-symbolic x integer?)
(check-type (type-of x) : (C→ Any Bool) -> integer?)
(check-type (type-of (+ x 1)) : (C→ Any Bool) -> integer?)
(check-type (type-of x 3.14) : (C→ Any Bool) -> real?)
(check-type (type-of #t) : (C→ Any Bool) -> boolean?)
(check-type (type-of #t 1) : (C→ Any Bool) -> any/c)
(check-type (type? integer?) : Bool -> #t)
(check-type (type? boolean?) : Bool -> #t)
(check-type (type? list?) : Bool -> #t)
(struct circle ([radius : Nat]))
(check-type (type? circle?) : Bool -> #t)
(check-type (type? any/c) : Bool -> #t)
(check-type (type? 1) : Bool -> #f)
(check-type (solvable? boolean?) : Bool -> #t)
(check-type (solvable? integer?) : Bool -> #t)
(check-type (solvable? real?) : Bool -> #t)
(check-type (solvable? (~> (bitvector 3) (bitvector 4))) : Bool -> #t)
(check-type (solvable? list?) : Bool -> #f)
;(struct circle (radius))
(check-type (solvable? circle?) : Bool -> #f)
(check-type (solvable? any/c) : Bool -> #f)
;; 7.1.2 Symbolic Unions
(define-symbolic b boolean?)
(define v (vector 1))
(check-type v : (CVectorof CPosInt))
(define w (vector 2 3))
(check-type v : (CVectorof CPosInt))
(define s (if b v w))
(check-type s : (Vectorof CPosInt)) ;{[b #(1)] [(! b) #(2 3)]}
(check-not-type s : (CVectorof CPosInt)) ; check union doesnt have concrete type
(check-type (type-of s) : (C→ Any Bool) -> vector?)
(check-type (eq? s v) : Bool -> b)
(check-type (eq? s w) : Bool -> (! b))
; (define-symbolic b boolean?)
(define-symbolic c boolean?)
(define v2 (if c "c" 0))
(check-type v2 : (U String Int))
(check-type v2 : (U CString CInt))
(check-not-type v2 : (CU CString CInt)) ; check not concrete
(check-type v2 : (U CString CInt))
(check-type v2 : (U CString CZero))
(define u (if b (vector v2) 4))
(check-type u : (U (CVectorof (U CString CZero)) Int)) ;{[b #({[c "c"] [(! c) 0]})] [(! b) 4]}
(check-type (type-of u) : (C→ Any Bool) -> any/c)
(check-type '(1 2) : (CListof CPosInt))
;> (define-symbolic b boolean?)
(define u2 (if b '(1 2) 3))
(check-type u2 : (U (CListof CPosInt) CPosInt))
(check-type (union? u2) : Bool -> #t)
(check-type (union? b) : Bool -> #f)
(define v3 (if b '(1 2) 3))
(check-type (union-contents v3)
: (CListof (CPair Bool (U (CListof CPosInt) CPosInt)))
-> (list (cons b '(1 2)) (cons (! b) 3)))
;; 7.1.3 Symbolic Lifting
(require (only-in "../../../rosette/rosette3.rkt" [string-length racket/string-length]))
(define (string-length [value : String] -> Nat)
(for/all ([str value])
(racket/string-length str)))
(check-type (string-length "abababa") : Nat -> 7)
(check-type (racket/string-length "abababa") : CNat -> 7)
(check-not-type (string-length "abababa") : CNat)
(typecheck-fail (string-length 3) #:with-msg "expected String")
;> (define-symbolic b boolean?)
(check-type (string-length (if b "a" "abababa")) : Nat -> (if b 1 7)) ;(ite b 1 7)
(check-not-type (string-length (if b "a" "abababa")) : CNat)
;; Typed Rosette rejects this program
(typecheck-fail (string-length (if b "a" 3)) #:with-msg "expected String")
;; need assert-type
;; TODO: this doesnt work yet because String has no pred
;; - and we cant use string? bc it's unlifted --- will always be assert fail
;(check-type (string-length (assert-type (if b "a" 3) : String)) : Nat -> 1)
;;(check-type (asserts) : CAsserts -> (list b))
(typecheck-fail (string-length (if b 3 #f)) #:with-msg "expected String")
;; not runtime exn: for/all: all paths infeasible
;; Making symbolic evaluation more efficient.
;; (require (only-in racket build-list))
(define limit 1000)
(define (slow [xs : (Listof CInt)] -> (U CFalse Int))
(and (= (length xs) limit) (car (map add1 xs))))
(define (fast [xs : (Listof CInt)] -> (U CFalse Int))
(for/all ([xs xs]) (slow xs)))
(define ys (build-list limit (lambda ([x : CNat]) x)))
(check-type ys : (CListof CInt))
(define-symbolic a boolean?)
(define xs (if a ys (cdr ys)))
(check-type xs : (Listof CInt))
(check-not-type xs : (CListof CInt))
(check-type (time (slow xs)) : (U CFalse Int) -> (if a 1 #f))
;; cpu time: 1 real time: 2 gc time: 0
;; {[a 1] [(! a) #f]}
(check-type (time (fast xs)) : (U CFalse Int) -> (if a 1 #f))
;; cpu time: 0 real time: 0 gc time: 0
;; {[a 1] [(! a) #f]}
(printf "First printed time should be slightly slower than second time\n")
;; define-lift
(require "../../../rosette/lib/lift3.rkt")
(define-lift lifted-string-length [(string?) racket/string-length])
(check-type (lifted-string-length "abababa") : Nat -> 7)
(check-not-type (lifted-string-length "abababa") : CNat)
;> (define-symbolic b boolean?)
(check-type (lifted-string-length (if b "a" "abababa"))
: Nat -> (if b 1 7)) ;(ite b 1 7)
;; typed rosette rejects this progrm
(typecheck-fail (lifted-string-length (if b "a" 3)) #:with-msg "expected.*String")
;; TODO: need type-assert
;; (check-type (lifted-string-length (assert-type (if b "a" 3) : String)) : Nat -> 1)
;; (check-type (asserts) : CAsserts -> (list b))
;; 7.2 Reflecting on Symbolic State
;> (define-symbolic a b boolean?)
(check-type (if a
(if b
#f
(pc))
#f) : Bool -> (&& a (! b)))
(check-type (assert a) : CUnit -> (void))
(check-type (asserts) : CAsserts -> (list a))
(check-type (assert b) : CUnit -> (void))
(check-type (asserts) : CAsserts -> (list b a))
(check-type (clear-asserts!) : CUnit -> (void))
(check-type (asserts) : CAsserts -> (list))
(printf "expected output: 4 and (list b a)\n")
(with-asserts
(begin (assert a)
(assert b)
4))
(check-type (asserts) : CAsserts -> (list))
;; term-cache
(clear-terms!)
(check-type (term-cache) : (CHashTable Any Any) -> (term-cache))
(check-type (hash-keys (term-cache)) : (CListof Any) -> (list))
(define-symbolic a1 b1 c1 d1 integer?)
(define (p? [x : Int] -> Bool)
(or (eq? x a1) (eq? x b1) (eq? x c1) (eq? x d1)))
(check-type (hash-values (term-cache)) : (CListof Any)); -> (list d1 c1 b1 a1))
;; make test more deterministic
(check-type (andmap p? (hash-values (term-cache))) : Bool -> #t)
;; (hash
;; #<syntax:23:0 d>
;; d
;; #<syntax:23:0 c>
;; c
;; #<syntax:23:0 b>
;; b
;; #<syntax:23:0 a>
;; a)
(check-type (* d1 (- (+ a1 b1) c1)) : Int -> (* d1 (- (+ a1 b1) c1)))
;(check-type (hash-keys (term-cache)) : CUnit -> (list (list * d (+ (+ a b) (- c))) d c b a))
(printf "expected output: hash with a-d and large arith op with all subexprs\n")
(pretty-print (term-cache))
;; (hash
;; (list * d (+ (+ a b) (- c)))
;; (* d (+ (+ a b) (- c)))
;; #<syntax:23:0 d>
;; d
;; #<syntax:23:0 c>
;; c
;; #<syntax:23:0 b>
;; b
;; #<syntax:23:0 a>
;; a
;; (list - c)
;; (- c)
;; (list + a b)
;; (+ a b)
;; (list + (+ a b) (- c))
;; (+ (+ a b) (- c)))
(check-type (clear-terms! (list c1 d1)) : CUnit -> (void))
(printf "expected output: hash with c and d missing\n")
(pretty-print (term-cache))
(check-type (clear-terms!) : CUnit -> (void))
(check-type (hash-keys (term-cache)) : (CListof Any) -> (list))

View File

@ -0,0 +1,345 @@
#lang s-exp "../../../rosette/rosette3.rkt"
(require "../../rackunit-typechecking.rkt"
"check-type+asserts.rkt")
;; subtyping among concrete
(check-type ((λ ([x : CPosInt]) x) ((λ ([x : CPosInt]) x) 1)) : CPosInt -> 1)
(check-type ((λ ([x : CZero]) x) ((λ ([x : CZero]) x) 0)) : CZero -> 0)
(check-type ((λ ([x : CNegInt]) x) ((λ ([x : CNegInt]) x) -1)) : CNegInt -> -1)
(check-type ((λ ([x : PosInt]) x) ((λ ([x : PosInt]) x) 1)) : PosInt -> 1)
(check-type ((λ ([x : Zero]) x) ((λ ([x : Zero]) x) 0)) : Zero -> 0)
(check-type ((λ ([x : NegInt]) x) ((λ ([x : NegInt]) x) -1)) : NegInt -> -1)
(check-type ((λ ([x : CNat]) x) ((λ ([x : CZero]) x) 0)) : CNat -> 0)
(check-type ((λ ([x : CNat]) x) ((λ ([x : CPosInt]) x) 1)) : CNat -> 1)
(check-type ((λ ([x : CNat]) x) ((λ ([x : CNat]) x) 1)) : CNat -> 1)
(typecheck-fail ((λ ([x : CPosInt]) x) ((λ ([x : CNat]) x) 1)))
(check-type ((λ ([x : Nat]) x) ((λ ([x : Zero]) x) 0)) : Nat -> 0)
(check-type ((λ ([x : Nat]) x) ((λ ([x : PosInt]) x) 1)) : Nat -> 1)
(check-type ((λ ([x : Nat]) x) ((λ ([x : Nat]) x) 1)) : Nat -> 1)
(typecheck-fail ((λ ([x : PosInt]) x) ((λ ([x : Nat]) x) 1)))
(check-type ((λ ([x : CInt]) x) ((λ ([x : CNegInt]) x) -1)) : CInt -> -1)
(check-type ((λ ([x : CInt]) x) ((λ ([x : CZero]) x) 0)) : CInt -> 0)
(check-type ((λ ([x : CInt]) x) ((λ ([x : CPosInt]) x) 1)) : CInt -> 1)
(check-type ((λ ([x : CInt]) x) ((λ ([x : CNat]) x) 1)) : CInt -> 1)
(check-type ((λ ([x : CInt]) x) ((λ ([x : CInt]) x) 1)) : CInt -> 1)
(typecheck-fail ((λ ([x : CPosInt]) x) ((λ ([x : CInt]) x) 1)))
(typecheck-fail ((λ ([x : CNat]) x) ((λ ([x : CInt]) x) 1)))
(check-type ((λ ([x : Int]) x) ((λ ([x : NegInt]) x) -1)) : Int -> -1)
(check-type ((λ ([x : Int]) x) ((λ ([x : Zero]) x) 0)) : Int -> 0)
(check-type ((λ ([x : Int]) x) ((λ ([x : PosInt]) x) 1)) : Int -> 1)
(check-type ((λ ([x : Int]) x) ((λ ([x : Nat]) x) 1)) : Int -> 1)
(check-type ((λ ([x : Int]) x) ((λ ([x : Int]) x) 1)) : Int -> 1)
(typecheck-fail ((λ ([x : PosInt]) x) ((λ ([x : Int]) x) 1)))
(typecheck-fail ((λ ([x : Nat]) x) ((λ ([x : Int]) x) 1)))
;; illustrates flattening
(define-type-alias A Int)
(define-type-alias B CString)
(define-type-alias C Bool)
(define-type-alias AC (U A C))
(define-type-alias BC (U B C))
(define-type-alias A-BC (U A BC))
(define-type-alias B-AC (U B AC))
(check-type ((λ ([x : A-BC]) x) ((λ ([x : B-AC]) x) "1")) : A-BC -> "1")
(check-type ((λ ([x : A-BC]) x) ((λ ([x : AC]) x) #t)) : A-BC -> #t)
(check-type ((λ ([x : B-AC]) x) ((λ ([x : A-BC]) x) "1")) : A-BC -> "1")
(check-type ((λ ([x : B-AC]) x) ((λ ([x : BC]) x) "1")) : A-BC -> "1")
(typecheck-fail ((λ ([x : BC]) x) ((λ ([x : B-AC]) x) "1")))
(typecheck-fail ((λ ([x : AC]) x) ((λ ([x : B-AC]) x) "1")))
;; subtyping between concrete and symbolic types
(check-type ((λ ([x : Int]) x) ((λ ([x : CInt]) x) 1)) : Int -> 1)
(typecheck-fail ((λ ([x : CInt]) x) ((λ ([x : Int]) x) 1)))
(check-type ((λ ([x : Bool]) x) ((λ ([x : CBool]) x) #t)) : Bool -> #t)
(typecheck-fail ((λ ([x : CBool]) x) ((λ ([x : Bool]) x) #t)))
(check-type ((λ ([x : (U CInt CBool)]) x) ((λ ([x : (CU CInt CBool)]) x) 1)) : (U CInt CBool))
(typecheck-fail ((λ ([x : (CU CInt CBool)]) x) ((λ ([x : (U CInt CBool)]) x) 1)))
(check-type ((λ ([x : (U Int Bool)]) x) ((λ ([x : (U CInt CBool)]) x) 1)) : (U CInt CBool))
(check-type ((λ ([x : (U CInt CBool)]) x) ((λ ([x : (U Int Bool)]) x) 1)) : (U CInt CBool))
;; add1 has a case-> type with cases for different subtypes of Int
;; to preserve some of the type information through the operation
(check-type (add1 9) : CPosInt -> 10)
(check-type (add1 0) : CPosInt -> 1)
(check-type (add1 -1) : (CU CNegInt CZero) -> 0)
(check-type (add1 -9) : (CU CNegInt CZero) -> -8)
(check-type (add1 (ann 9 : PosInt)) : PosInt -> 10)
(check-type (add1 (ann 0 : Zero)) : PosInt -> 1)
(check-type (add1 (ann 9 : Nat)) : PosInt -> 10)
(check-type (add1 (ann 0 : Nat)) : PosInt -> 1)
(check-type (add1 (ann -1 : NegInt)) : (U NegInt Zero) -> 0)
(check-type (add1 (ann -9 : NegInt)) : (U NegInt Zero) -> -8)
(check-type (add1 (ann 9 : Int)) : Int -> 10)
;; sub1 has a similar case-> type
(check-type (sub1 10) : CNat -> 9)
(check-type (sub1 0) : CNegInt -> -1)
(check-type (sub1 -1) : CNegInt -> -2)
(check-type (sub1 (ann 10 : PosInt)) : Nat -> 9)
(check-type (sub1 (ann 0 : Zero)) : NegInt -> -1)
(check-type (sub1 (ann -1 : NegInt)) : NegInt -> -2)
(check-type (+ 1 10) : CNat -> 11)
(check-type (+ -10 10) : CInt -> 0)
(check-type (+ (ann 1 : PosInt) (ann 10 : PosInt)) : Nat -> 11)
(check-type (+ (ann -10 : NegInt) (ann 10 : PosInt)) : Int -> 0)
;; if tests
;; if expr has concrete type only if test and both branches are concrete
(check-type (if #t 1 #f) : (CU CBool CInt))
(check-type (if #t 1 #f) : (U CBool CInt))
(check-type (if #t 1 #f) : (U Bool CInt))
(check-type (if #t 1 #f) : (U Bool Int))
(check-type (if #t 1 2) : CInt)
(check-type (if #t 1 2) : Int)
(check-type (if #t 1 2) : (CU CInt CBool))
(check-type (if #t 1 2) : (U Int Bool))
;; non-bool test
(check-type (if 1 2 3) : CInt)
;; else, if expr produces symbolic type
(define-symbolic b0 boolean?)
(define-symbolic i0 integer?)
(typecheck-fail (define-symbolic posint1 positive?)
#:with-msg "Expected a Rosette-solvable type, given positive?")
(typecheck-fail (lambda ([x : (Constant CInt)]) x)
#:with-msg "Constant requires a symbolic type")
(check-type b0 : Bool -> b0)
(check-type b0 : (Constant Bool) -> b0)
(check-not-type b0 : CBool)
(check-type i0 : Int -> i0)
(check-type i0 : (Constant Int) -> i0)
(check-type (if b0 1 2) : Int)
(check-not-type (if b0 1 2) : CInt)
(check-type (if #t i0 2) : Int)
(check-not-type (if #t i0 2) : CInt)
(check-type (if #t 2 i0) : Int)
(check-not-type (if #t 2 i0) : CInt)
(check-type (if b0 i0 2) : Int)
(check-type (if b0 1 #f) : (U CInt CBool))
(check-type (if b0 1 #f) : (U Int Bool))
;; slightly unintuitive case: (U Int Bool) <: (U CInt Bool), ok for now (see notes)
(check-type (if #f i0 #f) : (U CInt CBool))
(check-type (if #f i0 #f) : (U CInt Bool))
(check-type (if #f i0 #f) : (U Int Bool))
(check-type (if #f (+ i0 1) #f) : (U Int Bool))
;; BVs
(check-type bv : (Ccase-> (C→ CInt CBVPred CBV)
(C→ CInt CPosInt CBV)))
(typecheck-fail (bv "1" 2) #:with-msg "expected.*Int.*given.*String")
(check-type (bv 1 2) : CBV -> (bv 1 (bitvector 2)))
(check-type (bv 1 (bitvector 2)) : CBV -> (bv 1 (bitvector 2)))
(typecheck-fail (bv (ann 1 : Int) 2) #:with-msg "expected.*CInt")
(typecheck-fail (bv (ann 1 : Int) (bitvector 2)) #:with-msg "expected.*CInt")
(typecheck-fail (bv 0 0) #:with-msg "expected.*PosInt.*given.*Zero")
(check-type bitvector : (C→ CPosInt CBVPred))
(check-type (bitvector 3) : CBVPred)
(check-type ((bitvector 4) 1) : Bool -> #f)
(check-type ((bitvector 4) (bv 10 (bitvector 4))) : Bool)
(check-type (bitvector? "2") : Bool -> #f)
(check-type (bitvector? (bitvector 10)) : Bool -> #t)
;; bvops
(check-type (bveq (bv 1 3) (bv 1 3)) : Bool -> #t)
(typecheck-fail (bveq (bv 1 3) 1))
(check-type (bveq (bv 1 2) (bv 1 3)) : Bool) ; -> runtime exn
(check-runtime-exn (bveq (bv 1 2) (bv 1 3)))
(clear-asserts!)
(check-type (bvand (bv -1 4) (bv 2 4)) : BV
-> (bv 2 4))
(check-type (bvor (bv 0 3) (bv 1 3)) : BV
-> (bv 1 3))
(check-type (bvxor (bv -1 5) (bv 1 5)) : BV
-> (bv -2 5))
;; examples from rosette guide
(check-type (bvand (bv -1 4) (bv 2 4)) : BV -> (bv 2 4))
(check-type (bvor (bv 0 3) (bv 1 3)) : BV -> (bv 1 3))
(check-type (bvxor (bv -1 5) (bv 1 5)) : BV -> (bv -2 5))
(define-symbolic b boolean?)
(check-type (bvand (bv -1 4) (if b (bv 3 4) (bv 2 4))) : BV
-> (if b (bv 3 4) (bv 2 4)))
(check-type (bvshl (bv 1 4) (bv 2 4)) : BV -> (bv 4 4))
(check-type (bvlshr (bv -1 3) (bv 1 3)) : BV -> (bv 3 3))
(check-type (bvashr (bv -1 5) (bv 1 5)) : BV -> (bv -1 5))
;; TODO: see rosette issue #23 --- issue closed, won't fix
(check-type (bvshl (bv -1 4) (if b (bv 3 4) (bv 2 4))) : BV)
(check-type (bvneg (bv -1 4)) : BV -> (bv 1 4))
(check-type (bvneg (bv 0 4)) : BV -> (bv 0 4))
(define-symbolic z (bitvector 3))
(check-type (bvneg z) : BV)
(check-type (bvadd (bv -1 4) (bv 2 4)) : BV -> (bv 1 4))
(check-type (bvsub (bv 0 3) (bv 1 3)) : BV -> (bv -1 3))
(check-type (bvmul (bv -1 5) (bv 1 5)) : BV -> (bv -1 5))
;; TODO: see rosette issue #23 --- issue closed, won't fix
(check-type (bvadd (bvadd (bv -1 4) (bv 2 4)) (if b (bv 1 4) (bv 3 4))) : BV)
(check-type (bvsdiv (bv -3 4) (bv 2 4)) : BV -> (bv -1 4))
(check-type (bvudiv (bv -3 3) (bv 2 3)) : BV -> (bv 2 3))
(check-type (bvsmod (bv 1 5) (bv 0 5)) : BV -> (bv 1 5))
(check-type (bvsrem (bv -3 4) (if b (bv 2 4) (bv 3 4))) : BV
-> (if b (bv -1 4) (bv 0 4)))
(check-type (concat (concat (bv -1 4) (bv 0 1)) (bv -1 3)) : BV -> (bv -9 8))
(check-type (concat (concat (bv -1 4) (if b (bv 0 1) (bv 0 2))) (bv -1 3)) : BV
-> (if b (bv -9 8) (bv -25 9)))
(check-type (extract 2 1 (bv -1 4)) : BV -> (bv -1 2))
(check-type (extract 3 3 (bv 1 4)) : BV -> (bv 0 1))
(define-symbolic i j integer?)
(check-type (extract i j (bv 1 2)) : BV)
; -> {[(&& (= 0 j) (= 1 i)) (bv 1 2)] ...})
(check-type (sign-extend (bv -3 4) (bitvector 6)) : BV -> (bv -3 6))
(check-type (zero-extend (bv -3 4) (bitvector 6)) : BV -> (bv 13 6))
(define-symbolic c boolean?)
(check-type (zero-extend (bv -3 4) (if b (bitvector 5) (bitvector 6)))
: BV -> (if b (bv 13 5) (bv 13 6)))
(check-type+asserts
(zero-extend (bv -3 4) (assert-type (if b (bitvector 5) "bad") : BVPred))
: BV -> (bv 13 5) (list b))
(check-type+asserts (zero-extend (bv -3 4) (if c (bitvector 5) (bitvector 1)))
: BV -> (bv 13 5) (list c))
(check-type (bitvector->integer (bv -1 4)) : Int -> -1)
(check-type (bitvector->natural (bv -1 4)) : Int -> 15)
(check-type (bitvector->integer (if b (bv -1 3) (bv -3 4)))
: Int -> (if b -1 -3))
(check-type+asserts
(bitvector->integer (assert-type (if b (bv -1 3) "bad") : BV))
: Int -> -1 (list b))
(check-type (integer->bitvector 4 (bitvector 2)) : BV -> (bv 0 2))
(check-type (integer->bitvector 15 (bitvector 4)) : BV -> (bv -1 4))
(check-type+asserts (integer->bitvector (assert-type (if b pi 3) : Int)
(if c (bitvector 5) (bitvector 6)))
: BV -> (integer->bitvector 3 (if c (bitvector 5) (bitvector 6)))
(list (not b)))
;; TODO: check that CInt also has the right pred (do we want this?)
#;(check-type+asserts (integer->bitvector (assert-type (if b pi 3) : CInt)
(if c (bitvector 5) (bitvector 6)))
: BV -> (integer->bitvector 3 (if c (bitvector 5) (bitvector 6)))
(list (not b)))
(check-type (integer->bitvector 3
(if c (bitvector 5) (bitvector 6)))
: BV -> (if c (bv 3 5) (bv 3 6)))
;; case-> subtyping
(check-type ((λ ([f : (C→ Int Int)]) (f 10)) add1) : Int -> 11)
(check-type ((λ ([f : (Ccase-> (C→ Int Int))]) (f 10)) add1) : Int -> 11)
(check-type ((λ ([f : (Ccase-> (C→ Nat Nat)
(C→ Int Int))]) (f 10)) add1) : Int -> 11)
(check-not-type ((λ ([f : (Ccase-> (C→ Int Int))]) (f 10)) add1) : Nat)
(check-type ((λ ([f : (Ccase-> (C→ Nat Nat)
(C→ Int Int))]) (f 10)) add1) : Nat -> 11)
(typecheck-fail ((λ ([f : (Ccase-> (C→ Zero Zero)
(C→ Int Int))]) (f 10)) add1)
#:with-msg
(string-append "expected \\(Ccase-> \\(C→ Zero Zero\\) \\(C→ Int Int\\)\\), "
"given \\(Ccase-> .*\\(C→ NegInt \\(U NegInt Zero\\)\\) .*\\(C→ Zero PosInt\\) "
".*\\(C→ PosInt PosInt\\) .*\\(C→ Nat PosInt\\) .*\\(C→ Int Int\\)\\)"))
;; applying symbolic function types
(check-type ((λ ([f : (U (C→ CInt CInt))]) (f 10)) add1) : Int -> 11)
;; it's either (→ CInt CInt) or (→ CInt CBool), but not both, so
;; add1 can have this type even though it never returns a boolean
(check-type ((λ ([f : (U (C→ CInt CInt) (C→ CInt CBool))]) (f 10)) add1) : (U Int Bool) -> 11)
(check-type ((λ ([f : (U (C→ CInt CInt) (C→ CInt Bool))]) (f 10))
(if #t add1 positive?))
: (U CInt Bool) -> 11)
(check-type ((λ ([f : (U (C→ CInt CInt) (C→ CInt Bool))]) (f 10))
(if #t add1 positive?))
: (U Int Bool) -> 11)
;; concrete union of functions
(check-type ((λ ([f : (CU (C→ CInt CInt) (C→ CInt CBool))]) (f 10)) add1) : (CU CInt CBool) -> 11)
(check-type ((λ ([f : (CU (C→ CInt CInt) (C→ CInt CBool))]) (f 10))
(if #t add1 positive?))
: (CU CInt CBool) -> 11)
;; check BVPred as type annotation
;; CBV input annotation on arg is too restrictive to work as BVPred
(typecheck-fail ((λ ([bvp : BVPred]) bvp) (λ ([bv : CBV]) #t))
#:with-msg "expected BVPred.*given.*CBV")
(typecheck-fail ((λ ([bvp : BVPred]) bvp) (λ ([bv : BV]) #t))
#:with-msg "expected BVPred.*given.*BV")
;; BVpred arg must have Any input type
(check-type ((λ ([bvp : BVPred]) bvp) (λ ([bv : Any]) ((bitvector 2) bv))) : BVPred)
;; assert-type tests
(check-type+asserts (assert-type (sub1 10) : PosInt) : PosInt -> 9 (list))
(check-runtime-exn (assert-type (sub1 1) : PosInt))
(define-symbolic b1 b2 boolean?)
(check-type (clear-asserts!) : CUnit -> (void))
;; asserts directly on a symbolic union
(check-type+asserts (assert-type (if b1 1 #f) : Int) : Int -> 1 (list b1))
(check-type+asserts (assert-type (if b2 1 #f) : Bool) : Bool -> #f (list (not b2)))
;; asserts on the (pc)
(check-type+asserts (if b1 (assert-type 1 : Int) (assert-type #f : Int)) : Int
-> 1 (list b1))
(check-type+asserts (if b2 (assert-type 1 : Bool) (assert-type #f : Bool)) : Bool
-> #f (list (not b2)))
;; asserts on a define-symbolic value
(define-symbolic i1 integer?)
(check-type+asserts (assert-type i1 : PosInt) : PosInt -> i1 (list (< 0 i1)))
(check-type+asserts (assert-type i1 : Zero) : Zero -> i1 (list (= 0 i1)))
(check-type+asserts (assert-type i1 : NegInt) : NegInt -> i1 (list (< i1 0)))
;; TODO: should this assertion be equivalent to (<= 0 i1) ?
(check-type+asserts (assert-type i1 : Nat) : Nat -> i1 (list (not (< i1 0))))
;; asserts on other terms involving define-symbolic values
(check-type+asserts (assert-type (+ i1 1) : PosInt) : PosInt -> (+ 1 i1) (list (< 0 (+ 1 i1))))
(check-type+asserts (assert-type (+ i1 1) : Zero) : Zero -> (+ 1 i1) (list (= 0 (+ 1 i1))))
(check-type+asserts (assert-type (+ i1 1) : NegInt) : NegInt -> (+ 1 i1) (list (< (+ 1 i1) 0)))
(check-type+asserts (assert-type (if b1 i1 b2) : Int) : Int -> i1 (list b1))
(check-type+asserts (assert-type (if b1 i1 b2) : Bool) : Bool -> b2 (list (not b1)))
;; asserts on the (pc)
(check-type+asserts (if b1 (assert-type i1 : Int) (assert-type b2 : Int)) : Int
-> i1 (list b1))
(check-type+asserts (if b1 (assert-type i1 : Bool) (assert-type b2 : Bool)) : Bool
-> b2 (list (not b1)))
;; TODO: should assert-type cause some predicates to return true or return false?
(check-type+asserts (integer? (assert-type (if b1 i1 b2) : Int)) : Bool -> #t (list b1))
(check-type+asserts (integer? (assert-type (if b1 i1 b2) : Bool)) : Bool -> #f (list (not b1)))
(check-type+asserts (boolean? (assert-type (if b1 i1 b2) : Int)) : Bool -> #f (list b1))
(check-type+asserts (boolean? (assert-type (if b1 i1 b2) : Bool)) : Bool -> #t (list (not b1)))
(check-type (asserts) : (CListof Bool) -> (list))
;; tests for Constant
(define-symbolic ci1 integer?)
(define-symbolic bi1 bi2 boolean?)
(check-type ci1 : (Constant Int))
(check-type ci1 : Int)
(check-type ci1 : (Constant Num))
(check-type ci1 : Num)
;; homogeneous list of constants
(check-type (list bi1 bi2) : (CList (Constant Bool) (Constant Bool)))
(check-type (list bi1 bi2) : (CListof (Constant Bool)))
;; heterogeneous list of constants
(check-type (list ci1 bi1) : (CList (Constant Int) (Constant Bool)))
(check-type (cons ci1 (cons bi1 (list))) : (CList (Constant Int) (Constant Bool)))
(check-type
(lambda ([x : CInt] [lst : (CListof CBool)]) (cons x lst))
: (C→ CInt (CListof CBool) (CListof (CU CInt CBool))))
(check-not-type
(lambda ([x : Int] [lst : (CListof Bool)]) (cons x lst))
: (C→ Int (CListof Bool) (CListof (CU CInt CBool))))
(check-type
(lambda ([x : Int] [lst : (CListof Bool)]) (cons x lst))
: (C→ Int (CListof Bool) (CListof (U Int Bool))))
;; TODO: should these tests hold?
;(check-type ci1 : (U (Constant Int) (Constant Bool)))
;(check-type (list ci1 bi1) : (CListof (U (Constant Int) (Constant Bool))))
;(check-type (cons ci1 (cons bi1 (list))) : (CListof (U (Constant Int) (Constant Bool))))

View File

@ -0,0 +1,23 @@
#lang racket/base
(require macrotypes/examples/tests/do-tests)
(do-tests
"rosette3-tests.rkt" "General"
"rosette-guide-sec2-tests.rkt" "Rosette Guide, Section 2"
"rosette-guide-sec3-tests.rkt" "Rosette Guide, Section 3"
"rosette-guide-sec4-tests.rkt" "Rosette Guide, Section 4.1-4.2"
"rosette-guide-sec43-tests.rkt" "Rosette Guide, Section 4.3 BVs"
"rosette-guide-sec44-tests.rkt" "Rosette Guide, Section 4.4 Uninterp Fns"
"rosette-guide-sec45-tests.rkt" "Rosette Guide, Section 4.5 Procedures"
"rosette-guide-sec46-tests.rkt" "Rosette Guide, Section 4.6-4.8")
(do-tests
"rosette-guide-sec49-tests.rkt" "Rosette Guide, Section 4.9"
"rosette-guide-sec5-tests.rkt" "Rosette Guide, Section 5 Structures"
"rosette-guide-sec6-tests.rkt" "Rosette Guide, Section 6 Libraries"
"rosette-guide-sec7-tests.rkt" "Guide Sec. 7 Reflecting on Symbolic Values")
(do-tests "bv-tests.rkt" "BV SDSL - General"
"bv-ref-tests.rkt" "BV SDSL - Hacker's Delight synthesis")