6  Conjuctions and Disjunctions

Goals may be combined using the forms %and and %or to form compound goals. (For %not, see sec 8.2.) Eg,

(%which (x)
  (%and (%member x '(1 2 3))
        (%< x 3)))

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. The first solution is

([x 1])

Typing (%more) gives another solution:

([x 2])

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))))

lists all x that are members of either list.

           ([x 1])
(%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 sec 2.2 using %and and %or:

(define %computer-literate
  (%rel (person)
    [(person)
     (%or
       (%and (%knows person
	       'TeX)
	     (%knows person
	       'Scheme))
       (%and (%knows person
	       'TeX)
	     (%knows person
	       'Prolog)))]))

Or, more succinctly:

(define %computer-literate
  (%rel (person)
    [(person)
      (%and (%knows person
	      'TeX)
        (%or (%knows person
	       'Scheme)
	     (%knows person
	       'Prolog)))]))

We can even dispense with the %rel altogether:

(define %computer-literate
  (lambda (person)
    (%and (%knows person
	    'TeX)
      (%or (%knows person
	     'Scheme)
	(%knows person
	  'Prolog)))))

This last looks like a conventional Scheme predicate definition, and is arguably the most readable format for a Scheme programmer.