Skip to content

Commit

Permalink
Merge pull request #534 from eraserhd/amb-choose-operator
Browse files Browse the repository at this point in the history
Add element-of to :std/amb
  • Loading branch information
vyzo authored Jun 8, 2020
2 parents e53c976 + 8a21849 commit e55a9c9
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 23 deletions.
7 changes: 7 additions & 0 deletions doc/reference/amb.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ Procedural form of `amb-collect`

Predicate that returns true if *e* is an exception raised because the amb search was exhausted.

### element-of
```
(element-of list) -> any
```

Ambiguous choice from a list; may evaluate and return any element of *list*.

## Example

Here is the well known dwelling house puzzle:
Expand Down
60 changes: 38 additions & 22 deletions src/std/amb-test.ss
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,50 @@
(else #t))))

(def (solve-dwelling-puzzle)
(let ((baker (amb 1 2 3 4 5))
(cooper (amb 1 2 3 4 5))
(fletcher (amb 1 2 3 4 5))
(miller (amb 1 2 3 4 5))
(smith (amb 1 2 3 4 5)))
(begin-amb
(let ((baker (amb 1 2 3 4 5))
(cooper (amb 1 2 3 4 5))
(fletcher (amb 1 2 3 4 5))
(miller (amb 1 2 3 4 5))
(smith (amb 1 2 3 4 5)))

;; They live on different floors.
(required (distinct? (list baker cooper fletcher miller smith)))
;; They live on different floors.
(required (distinct? (list baker cooper fletcher miller smith)))

;; Baker does not live on the top floor.
(required (not (= baker 5)))
;; Baker does not live on the top floor.
(required (not (= baker 5)))

;; Cooper does not live on the bottom floor.
(required (not (= cooper 1)))
;; Cooper does not live on the bottom floor.
(required (not (= cooper 1)))

;; Fletcher does not live on either the top or the bottom floor.
(required (not (= fletcher 5)))
(required (not (= fletcher 1)))
;; Fletcher does not live on either the top or the bottom floor.
(required (not (= fletcher 5)))
(required (not (= fletcher 1)))

;; Miller lives on a higher floor than does Cooper.
(required (> miller cooper))
;; Miller lives on a higher floor than does Cooper.
(required (> miller cooper))

;; Smith does not live on a floor adjacent to Fletcher's.
(required (not (= (abs (- smith fletcher)) 1)))
;; Smith does not live on a floor adjacent to Fletcher's.
(required (not (= (abs (- smith fletcher)) 1)))

;; Fletcher does not live on a floor adjacent to Cooper's.
(required (not (= (abs (- fletcher cooper)) 1)))
;; Fletcher does not live on a floor adjacent to Cooper's.
(required (not (= (abs (- fletcher cooper)) 1)))

`((baker ,baker) (cooper ,cooper) (fletcher ,fletcher) (miller ,miller) (smith ,smith))))
`((baker ,baker) (cooper ,cooper) (fletcher ,fletcher) (miller ,miller) (smith ,smith)))))

(check (solve-dwelling-puzzle) => '((baker 3) (cooper 2) (fletcher 4) (miller 5) (smith 1))))))
(check (solve-dwelling-puzzle) => '((baker 3) (cooper 2) (fletcher 4) (miller 5) (smith 1))))
(test-case "all-of"
(def (odds<=6)
(begin-amb
(let (x (amb 1 2 3 4 5 6))
(required (odd? x))
(all-of x))))
(check (odds<=6) => '(1 3 5))
(check (begin-amb (all-of (amb))) => '()))
(test-case "element-of"
(def (even-between-1-and-3)
(begin-amb
(let (x (element-of '(1 2 3)))
(required (even? x))
x)))
(check (even-between-1-and-3) => 2))))
6 changes: 5 additions & 1 deletion src/std/amb.ss
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
:std/misc/shuffle)
(export begin-amb begin-amb-random amb amb-find one-of amb-collect all-of amb-assert required
amb-do amb-do-find amb-do-collect
amb-exhausted?)
amb-exhausted?
element-of)

(defstruct (amb-completion <error>) ())

Expand Down Expand Up @@ -113,3 +114,6 @@
(let (next (thunk))
(amb-results (cons next (amb-results)))
((amb-fail))))))

(def (element-of xs)
(amb-do (map (cut lambda () <>) xs)))

0 comments on commit e55a9c9

Please sign in to comment.