CLIPS> (batch test.clp)
TRUE
CLIPS>
(assert
(a 23)
(b 43)
(c 27)
(d 43)
(e 55))
<Fact-5>
CLIPS> CLIPS> (find-all-facts ((?f c)) TRUE)
(<Fact-3>)
CLIPS>
(do-for-all-facts ((?f c)) TRUE
(printout t ?f:implied crlf)
(printout t (nth$ 1 ?f:implied) crlf))
(27)
27
CLIPS> (deftemplate f (slot value))
CLIPS> (assert (f (value 1)))
<Fact-6>
CLIPS>
(do-for-all-facts ((?f f)) TRUE (printout t ?f:value crlf))
1
CLIPS>Use the load command to load constructs (defrule, deftemplate, deffacts ...) from a file. Use the batch command to execute functions/commands contained in a file.CLIPS> (batch test.clp)
TRUE
CLIPS>
(assert
(a 23)
(b 43)
(c 27)
(d 43)
(e 55))
<Fact-5>
CLIPS>You can also place constructs in a batch file along with commands/functions, but it is better to load them using the load command (since the load command only expects constructs, error handling for a misplaced parenthesis allows the command to more easily move on to the next construct).
There are numerous examples of using the fact query functions in section 12.9.12 of the Basic Programming Guide. It is easier to use these functions with facts with a corresponding deftemplate that has slots, but you can also use them with ordered facts using the "implied" slot.CLIPS> (find-all-facts ((?f c)) TRUE)
(<Fact-3>)
CLIPS>
(do-for-all-facts ((?f c)) TRUE
(printout t ?f:implied crlf)
(printout t (nth$ 1 ?f:implied) crlf))
(27)
27
CLIPS> (deftemplate f (slot value))
CLIPS> (assert (f (value 1)))
<Fact-6>
CLIPS>
(do-for-all-facts ((?f f)) TRUE (printout t ?f:value crlf))
1
CLIPS>
(defrule hello
=>
(assert (hello)))
(printout t "Hello World" crlf)
(assert (goodbye)))CLIPS> (clear)
CLIPS> (watch compilations)
CLIPS> (load rules.clp)
Defining defrule: hello +j+j
[CSTRCPSR1] Expected the beginning of a construct.
FALSE
CLIPS> CLIPS> (clear)
CLIPS> (batch rules.clp)
TRUE
CLIPS> (defrule hello
=>
(assert (hello)))
CLIPS> (printout t "Hello World" crlf)
Hello World
CLIPS> (assert (goodbye)))
<Fact-1>
CLIPS> CLIPS>
(defmethod query ((?relation SYMBOL))
(bind ?results (create$))
(progn$ (?f (get-fact-list))
(if (eq (fact-relation ?f) ?relation)
then
(bind ?results (create$ ?f ?results))))
?results)
CLIPS>
(defmethod query ((?relation SYMBOL) (?value OBJECT))
(bind ?results (create$))
(progn$ (?f (query ?relation))
(if (and (member$ implied (fact-slot-names ?f))
(member$ ?value (fact-slot-value ?f implied)))
then
(bind ?results (create$ ?f ?results))))
?results)
CLIPS> (assert (a 1) (a 2) (b 2) (b 3))
<Fact-4>
CLIPS> (query a)
(<Fact-2> <Fact-1>)
CLIPS> (query b 2)
(<Fact-3>)
CLIPS> Basically people who dislike LISP don't like CLIPS syntax because it looks like LISP and people who like LISP don't like CLIPS syntax because it doesn't behave like LISP.
CLIPS has LISP-like syntax, but it was never intended to be a LISP-like programming language. It is first and foremost a rule engine. Back in the 80s, most of the state-of-the-art rule engines were written in LISP. The syntax of CLIPS was based on a LISP-based product named ART that had been used to develop several expert systems at NASA/Johnson Space Center. A subset of ART syntax was implemented to make porting ART applications to CLIPS easier, but in retrospect we should have used a more C-like syntax. I'd learned a bit of prolog in college and started programming in C, LISP, Flavors, and ART after graduating, so switching between different syntaxes never bothered me, but many people find LISP syntax to be bizarre. The market voted on the merits of LISP for rule engines and it voted thumbs down.CLIPS doesn't support nested lists--multifield values are more like vectors--so semantically it's pretty far removed from LISP in being able to treat programs as data (and vice veras) and is more similar to C/Java in that regard. All of the LISP-like syntax in CLIPS could be replaced with C-like syntax without any loss of functionality. It would be of far more benefit to the majority of CLIPS users who have little to no familiarity with LISP to make CLIPS more C-like than making it more LISP-like.
...
Also, the distinction between load and batch is a nice thing. While we use batch* almost exclusively, I do see the need for the two, especially that you can use batch to simulate input. Really cool feature. The distinction threw me off for a little but when I first started but not anymore.