main
Matthew Butterick 6 years ago
parent 2ef93b91a1
commit fa87b1b606

@ -49,6 +49,16 @@
var))
($csp-constraints csp)))
(define/contract (update-conflicts csp name conflicts)
($csp? $var-name? (listof $var-name?) . -> . $csp?)
($csp
(for/list ([var ($csp-vars csp)])
(match var
[($var (? (λ (x) (eq? x name))) vals past _)
(+$avar name vals past conflicts)]
[else var]))
($csp-constraints csp)))
(define/contract (first-unassigned-variable csp)
($csp? . -> . (or/c #false (and/c $var? (not/c $avar?))))
(for/first ([var (in-list ($csp-vars csp))]
@ -75,9 +85,10 @@
(define/contract (forward-check csp aname)
($csp? $var-name? . -> . $csp?)
#R csp
(define aval (first ($csp-vals csp aname)))
(define (filter-vals var)
(match-define ($var name vals _ _) var)
(match-define ($var name vals past conflicts) var)
(match (($csp-constraints csp) . relating . (list aname name))
[(? empty?) var]
[constraints
@ -90,8 +101,8 @@
(proc aval val)))))
val))
(unless (pair? new-vals)
(raise (inconsistency-signal csp)))
(+$var name new-vals (cons aname ($var-past var)) ($var-conflicts var))]))
(raise (inconsistency-signal past)))
(+$var name new-vals (cons aname past) conflicts)]))
($csp
(for/list ([var (in-list ($csp-vars csp))])
@ -101,9 +112,16 @@
($csp-constraints csp)))
(check-equal?
;; no forward checking when no constraints
($csp-vars (forward-check ($csp (list (+$avar 'a '(1)) (+$var 'b (range 2))) null) 'a))
(list (+$avar 'a '(1)) (+$var 'b '(0 1))))
(check-equal?
($csp-vars (forward-check (forward-check ($csp (list (+$avar 'a '(1)) (+$avar 'b '(0)) (+$var 'c '(0 1 2)))
(list ($constraint '(a c) (negate =))
($constraint '(b c) (negate =)))) 'a) 'b))
(list (+$avar 'a '(1)) (+$avar 'b '(0) '()) (+$var 'c '(2) '(b a))))
(check-equal?
;; no inconsistency: b≠c not checked when fc is relative to a
($csp-vars (forward-check ($csp (list (+$avar 'a '(1)) (+$var 'b (range 2)) (+$var 'c '(0)))
@ -143,11 +161,19 @@
(match (select-unassigned-variable csp)
[#false (yield csp)]
[($var name vals _ _)
(for ([val (in-list (order-domain-values vals))])
(with-handlers ([inconsistency-signal? void])
(for/fold ([conflicts null]
#:result (void))
([val (in-list (order-domain-values vals))])
#R conflicts
(with-handlers ([inconsistency-signal?
(λ (sig)
(match sig
[(inconsistency-signal new-conflicts)
(append new-conflicts conflicts)]))])
(let* ([csp (assign-val csp name val)]
[csp (inference csp name)])
(backtrack csp))))]))))
(backtrack csp))
conflicts))]))))
(define/contract (solve* csp
#:finish-proc [finish-proc $csp-vars]
@ -169,10 +195,10 @@
(define (<> a b) (not (= a b)))
(define (neq? a b) (not (eq? a b)))
#;(parameterize ([current-inference forward-check])
(time (solve* ($csp (list (+$var 'a (range 3))
(+$var 'b (range 3))
(+$var 'c (range 3)))
(parameterize ([current-inference forward-check])
(time (solve* ($csp (list (+$var 'a '(1))
(+$var 'b '(1))
(+$var 'c '(1)))
(list ($constraint '(a b) <>)
($constraint '(a c) <>)
($constraint '(b c) <>))))))

Loading…
Cancel
Save