-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththreads.rkt
102 lines (78 loc) · 2.89 KB
/
threads.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
#lang rosette
(require rosette/solver/smt/z3)
(require data/heap)
(define problem%
(class object%
(super-new)
(init smt priority hook)
(define smt-problem smt)
(define problem-priority priority)
(define solution-callback hook)
(define/public (get-callback)
solution-callback)
(define/public (get-problem)
smt-problem)
(define/public (get-priority)
problem-priority)))
(define (problem<? l r)
(< (send l get-priority) (send r get-priority)))
(define (problem-heap)
(make-heap problem<?))
(define (engine)
(thread
(lambda ()
(letrec ((loop
(lambda ()
(with-handlers ([exn:break? (lambda (x) '())])
(let* ((stuff (thread-receive))
(problem (car stuff))
(hook (cdr stuff))
(solver (z3)))
(with-handlers ([exn:break? (lambda (x) (solver-shutdown solver))])
(solver-clear solver)
(solver-assert solver (list problem))
(with-handlers ([exn:fail?
(lambda (e) (if (exn:break? e)
(raise e)
(begin
(println e)
(hook problem e))))])
(let ((result (solver-check solver)))
(hook problem result)))
(solver-shutdown solver)
(loop)))))))
(loop)))))
(define (engine-solve engine formula hook)
(thread-send engine (cons formula hook)))
(define (engine-stop engine)
(break-thread engine))
(define (engines n)
(for/list ([i (in-range n)])
(engine)))
(define (engines-solve engines formula hook)
(engine-solve (list-ref engines (random (length (cdr engines)))) formula hook))
(define (engines-stop engines)
(for ([e engines])
(engine-stop e)))
(define balance-size 10)
(define engines%
(class object%
(super-new)
(init n)
(define smt-solvers (engines n))
(define problem-queue (problem-heap))
(define (solve-one)
(let ((x (heap-min problem-queue)))
(heap-remove! problem-queue x)
(engines-solve smt-solvers (send x get-problem) (send x get-callback))))
(define/public (solve formula priority hook)
(heap-add! problem-queue (new problem% [smt formula] [priority priority] [hook hook]))
(when (> (heap-count problem-queue) balance-size)
(solve-one)))
(define/public (drain)
(if (> (heap-count problem-queue) 0)
(begin
(solve-one)
(drain))
(engines-stop smt-solvers)))))
(provide engine engines engine-solve engines-solve engine-stop engines-stop engines%)