-
Notifications
You must be signed in to change notification settings - Fork 5
/
queue-rosette.rkt
162 lines (126 loc) · 5.16 KB
/
queue-rosette.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#lang s-exp rosette
(require "queue-racket.rkt" "special.rkt" "ops-rosette.rkt")
(provide queue-in-rosette% queue-out-rosette%)
(define queue-in-rosette%
(class* special% (equal<%> printable<%>)
(super-new)
(init-field get-fresh-val
[size 4]
[init (make-vector size #f)]
[queue (make-vector size #f)]
[ref #f])
(public pop create-concrete clone)
(define/public (custom-print port depth)
(print `(queue-in-rosette% content: ,init ,queue) port depth))
(define/public (custom-write port)
(write `(queue-in-rosette% content: ,init ,queue) port))
(define/public (custom-display port)
(display `(queue-in-rosette% content: ,init ,queue) port))
(define/public (equal-to? other recur)
(and (is-a? other queue-in-rosette%)
(equal? queue (get-field* queue other))))
(define/public (equal-hash-code-of hash-code)
(hash-code queue))
(define/public (equal-secondary-hash-code-of hash-code)
(hash-code queue))
(define (get-size [index 0])
(if (vector-ref queue index)
(get-size (add1 index))
index))
;; Create concrete memory object by evaluating symbolic memory.
(define (create-concrete eval)
(new queue-in-racket% [queue (eval init)]))
;; Clone a new queue object with the same queue.
;; Use this method to clone new memory for every program interpretation.
(define (clone [ref #f])
(new queue-in-rosette% [ref ref] [init init] [queue (vector-copy queue)]
[get-fresh-val get-fresh-val]))
(define (pop-spec)
(define size (get-size))
(define val (vector-ref init size))
(unless val
(set! val (get-fresh-val))
(vector-set! init size val))
(vector-set! queue size val)
val)
(define (pop-cand)
(define size (get-size))
(define val (vector-ref init size))
(vector-set! queue size val)
val)
(define (pop)
(if ref (pop-cand) (pop-spec)))
))
(define queue-out-rosette%
(class* special% (equal<%> printable<%>)
(super-new)
(init-field get-fresh-val
[ref #f]
[size 4]
[queue (make-vector size #f)])
(public push create-concrete clone)
(define/public (custom-print port depth)
(print `(queue-out-rosette% content: ,queue size: ,(get-size)) port depth))
(define/public (custom-write port)
(write `(queue-out-rosette% content: ,queue size: ,(get-size)) port))
(define/public (custom-display port)
(display `(queue-out-rosette% content: ,queue size: ,(get-size)) port))
(define/public (equal-to? other recur)
;; (pretty-display `(equal-to? ,queue ,(get-field queue other)
;; ,(and (is-a? other queue-out-rosette%)
;; (equal? queue (get-field queue other)))))
(and (is-a? other queue-out-rosette%)
(equal? queue (get-field* queue other))))
(define/public (equal-hash-code-of hash-code)
(hash-code queue))
(define/public (equal-secondary-hash-code-of hash-code)
(hash-code queue))
(define (get-size [index 0])
(if (vector-ref queue index)
(get-size (add1 index))
index))
(define/public (get-at index) (vector-ref queue index))
;; Create concrete memory object by evaluating symbolic memory.
(define (create-concrete eval)
(new queue-out-racket% [queue (eval queue)]))
;; Clone a new queue object with the same queue.
;; Use this method to clone new memory for every program interpretation.
(define (clone [ref #f])
(new queue-out-rosette% [ref ref] [queue (vector-copy queue)] [get-fresh-val get-fresh-val]))
(define (push-spec val)
(vector-set! queue (get-size) val))
(define (push-cand val)
(define size (get-size))
(define val-ref (send* ref get-at size))
(assert (equal? val val-ref) "push-cand: push a value different from spec does")
(vector-set! queue size val))
(define (push val)
(if ref (push-cand val) (push-spec val)))
))
(define (test1)
(define func (lambda () (define-symbolic* val number?) val))
(define q-init (new queue-in-rosette% [get-fresh-val func]))
(define q (send q-init clone))
(pretty-display `(pop ,(send q pop)))
(pretty-display `(pop ,(send q pop)))
(pretty-display `(queue-init ,q-init))
(pretty-display `(queue ,q))
(define q1 (send q-init clone q))
(pretty-display `(pop ,(send q1 pop)))
(pretty-display `(queue-init ,q1))
(pretty-display `(pop ,(send q1 pop)))
(pretty-display `(pop ,(send q1 pop))) ;; assert: pop-cand: pop more than spec does
)
(define (test2)
(define func (lambda () (define-symbolic* val number?) val))
(define q-init (new queue-out-rosette% [get-fresh-val func]))
(define q (send q-init clone))
(send q push 1)
(send q push 2)
(pretty-display `(queue-init ,q-init))
(pretty-display `(queue ,q))
(define q2 (send q-init clone q))
(send q2 push 1)
(pretty-display `(queue ,q2))
(send q2 push 22) ;; assert: push-cand: push a value different from spec does
)