(deffacts initial-phase (phase choose-player)) (defrule player-select (phase choose-player) ; control pattern => (printout t "Who moves first (Computer: c " "Human: h)? ") (assert (player-select (read)))) (defrule good-player-choice ?phase <- (phase choose-player) ?choice <- (player-select ?player&c | h) => (retract ?phase ?choice) (assert (player-move ?player))) (defrule bad-player-choice ; if bad, then back to previous page ?phase <- (phase choose-player) ?choice <- (player-select ?player&~c&~h) => (retract ?phase ?choice) (assert (phase choose-player)) (printout t "Choose c or h only." crlf) )
(defrule get-human-move (player-move h) (pile-size ?size) (test (> ?size 1)) => (printout t "How many sticks do you wish to take? ") (assert (human-takes (read)))) (defrule good-human-move ?whose-turn <- (player-move h) (pile-size ?size) ?number-taken <- (human-takes ?choice) (test (and (integerp ?choice) (>= ?choice 1) (<= ?choice 3) (< ?choice ?size))) => (retract ?whose-turn ?number-taken) (printout t "Human made a valid move." crlf) (assert (player-move c))) (defrule bad-human-move ?whose-turn <- (player-move h) (pile-size ?size) ?number-taken <- (human-takes ?choice) (test (or (not (integerp ?choice)) (< ?choice 1) (> ?choice 3) (>= ?choice ?size))) => (printout t "Human made an invalid move." crlf) (retract ?whose-turn ?number-taken) (assert (player-move h)))
(pile-size ?size) (test (> ?size 1)) (pile-size ?size&:(> ?size 1)) (data ?item&:(stringp ?item)|(symbolp ?item))
(deftemplate take-sticks (slot how-many) ; Number of sticks to take. (slot for-remainder)) ; Remainder when stack is ; divided by 4. (deffacts take-sticks-information (take-sticks (how-many 1) (for-remainder 1)) (take-sticks (how-many 1) (for-remainder 2)) (take-sticks (how-many 2) (for-remainder 3)) (take-sticks (how-many 3) (for-remainder 0))) (defrule computer-move ?whose-turn <- (player-move c) ?pile <- (pile-size ?size&:(> ?size 1)) (take-sticks (how-many ?number) (for-remainder ?X&:(= ?X (mod ?size 4)))) => (retract ?whose-turn ?pile) (assert (pile-size (- ?size ?number))) (assert (player-move h)))
(defrule shut-off-electricity (or (emergency (type flood)) (extinguisher-sysetem (type water-sprinkler) (status on)) => (printout t "Shut off the electricity." crlf))
(defrule use-carbon-dioxide-extinguisher ?system <- (extingisher-system (type carbon-dioxide) (status off)) (or (emergency (type class-B-fire)) (and (emergency (type class-C-fire)) (electrical-power (status off)))) => (modify ?system (status on)) (printout t "Use carbon dioxide extinguisher" crlf))
(defrule largest-number (number ?x) (not (number ?y&:(> ?y ?x))) => (printout t "Largest number is " ?x crlf))
Note: Variables bound within a not CE retain their value only within the scope of the not CE.
Example: Find the largest integer
(defrule operator-alert-for-emergency (exist (emergency)) => (printout t "Emergency: Operator Alert" crlf) (assert (operator-alert)))
Demo:
(deftemplate emergency (slot type) (slot location)) (deftemplate fire-squad (slot name) (slot location)) (deftemplate evacuated (slot building)) (defrule all-fires-being-handled (forall (emergency (type fire) (location ?where)) (fire-squad (location ?where)) (evacuated (building ?where))) => (printout t "All buildings that are on fire " crlf "have been evacuated and " crlf "have firefighters on location." crlf))
Example:
(defrule noxious-fumes-present (emergency (type fire)) (noxious-fumes-present) => (assert (use-oxygen-mask))) (defrule noxious-fumes-present (logical (emergency (type fire)) (noxious-fumes-present)) => (assert (use-oxygen-mask)))
Example: logical CE
Previous Pattern Matching Up TOC Next Modular Design and Execution Control