-
Notifications
You must be signed in to change notification settings - Fork 0
/
queue.lisp
60 lines (53 loc) · 2.22 KB
/
queue.lisp
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
;;;; This file defines a pretty trivial Coalton wrapper around Eric O'Connor's queues library,
;;;; https://github.com/oconnore/queues.
;; The implementation of A* in water-sort/package:find-solution uses a PriorityQueue to track its frontier of
;; nodes to search.
(uiop:define-package :water-sort/queue
(:use :coalton :coalton-prelude)
(:local-nicknames (#:q :queues))
(:export
#:PriorityQueue
#:new
#:insert!
#:remove-min!
#:peek-min!))
(in-package :water-sort/queue)
(coalton-toplevel
(repr :native q:priority-queue)
(define-type (PriorityQueue :cost :value))
(declare get-queue-lt? (Ord :cost => Unit -> (Tuple :cost :value -> Tuple :cost :value -> Boolean)))
(define (get-queue-lt?)
(fn (a b)
(match (Tuple a b)
((Tuple (Tuple a _) (Tuple b _)) (< a b)))))
(declare make-priority-queue-from-lt? (Ord :cost =>
(Tuple :cost :value -> Tuple :cost :value -> Boolean)
-> PriorityQueue :cost :value))
(define (make-priority-queue-from-lt? lt?)
(lisp (PriorityQueue :cost :value) (lt?)
(cl:flet ((coalton-priority-queue-lt? (a b)
(call-coalton-function lt? a b)))
(q:make-queue ':priority-queue :compare #'coalton-priority-queue-lt?))))
(declare new (Ord :cost => Unit -> PriorityQueue :cost :value))
(define (new)
(make-priority-queue-from-lt? (get-queue-lt?)))
(declare insert! (Ord :cost => PriorityQueue :cost :value -> :cost -> :value -> Unit))
(define (insert! q cost val)
(let pair = (Tuple cost val))
(lisp Unit (q pair)
(q:qpush q pair)
Unit))
(declare remove-min! (Ord :cost => PriorityQueue :cost :value -> Optional (Tuple :cost :value)))
(define (remove-min! q)
(lisp (Optional (Tuple :cost :value)) (q)
(cl:multiple-value-bind (pair presentp) (q:qpop q)
(cl:if presentp
(Some pair)
None))))
(declare peek-min! (Ord :cost => PriorityQueue :cost :value -> Optional (Tuple :cost :value)))
(define (peek-min! q)
(lisp (Optional (Tuple :cost :value)) (q)
(cl:multiple-value-bind (pair presentp) (q:qtop q)
(cl:if presentp
(Some pair)
None)))))