6 Conjunctions and Disjunctions
Goals may be combined using the forms %and and %or to form compound goals. (For %not, see Negation as Failure.) Eg,
> (%which (x) (%and (%member x '(1 2 3)) (%< x 3))) '((x . 1))
gives solutions for x that satisfy both the argument goals of the %and. Ie, x should both be a member of '(1 2 3) and be less than 3. Typing (%more) gives another solution:
> (%more) '((x . 2))
> (%more) #f
There are no more solutions, because [x 3] satisfies the first but not the second goal.
Similarly, the query
> (%which (x) (%or (%member x '(1 2 3)) (%member x '(3 4 5)))) '((x . 1))
lists all x that are members of either list.
> (%more) '((x . 2))
> (%more) '((x . 3))
> (%more) '((x . 3))
> (%more) '((x . 4))
> (%more) '((x . 5))
(Yes, ([x 3]) is listed twice.)
We can rewrite the predicate %computer-literate from Predicates with Rules using %and and %or:
(define %computer-literate (%rel (person) [(person) (%or (%and (%knows person 'TeX) (%knows person 'Racket)) (%and (%knows person 'TeX) (%knows person 'Prolog)))]))
Or, more succinctly:
(define %computer-literate (%rel (person) [(person) (%and (%knows person 'TeX) (%or (%knows person 'Racket) (%knows person 'Prolog)))]))
We can even dispense with the %rel altogether:
(define %computer-literate (lambda (person) (%and (%knows person 'TeX) (%or (%knows person 'Racket) (%knows person 'Prolog)))))
This last looks like a conventional Racket predicate definition, and is arguably the most readable format for a Racket programmer.