I jsut started to learn CLIPS and I made a simple sorting algorithm to sort multifield variables in ascending order, the problem is that the return multifield variable isn't modified during the algorithm
(deffunction sort (?multifield)
(bind ?size (length$ ?multifield))
(loop-for-count (?i 1 (- ?size 1))
(loop-for-count (?j (+ ?i 1) ?size)
(printout t (nth$ ?i ?multifield) " " (nth$ ?j ?multifield) crlf)
(if (> (nth$ ?i ?multifield) (nth$ ?j ?multifield)) then
(printout t "> " (nth$ ?i ?multifield) " " (nth$ ?j ?multifield) crlf)
(bind ?temp (nth$ ?i ?multifield))
(replace$ ?multifield ?i ?i (nth$ ?j ?multifield))
(replace$ ?multifield ?j ?j ?temp)
(printout t "> que" (nth$ ?i ?multifield) " " (nth$ ?j ?multifield) crlf)
)
)
)
(return ?multifield)
)
This is a simple case where you can see the printed conditions and a correct execution of the algorithm but an incorrect return value:
CLIPS> (sort (create$ 3 6 4 1))
3 6
3 4
3 1
before replacement multifield(i) and multifield(j) 3 1
after replacement multifield(i) and multifield(j) 3 1
6 4
before replacement multifield(i) and multifield(j) 6 4
after replacement multifield(i) and multifield(j) 6 4
6 1
before replacement multifield(i) and multifield(j) 6 1
after replacement multifield(i) and multifield(j) 6 1
4 1
before replacement multifield(i) and multifield(j) 4 1
after replacement multifield(i) and multifield(j) 4 1
(3 6 4 1)
Citing from the docs
The replace$ function replaces a range of field in a multifield value with a series of single-field and/or multifield values and returns a new multifield value containing the replacement values within the original multifield value.
So, replace$
does not modify the multifield passed in, but returns a new mutifield with the replaced values, which you have to bind again ...
(deffunction mysort (?multifield)
(bind ?size (length$ ?multifield))
(loop-for-count (?i 1 (- ?size 1))
(loop-for-count (?j (+ ?i 1) ?size)
(printout t (nth$ ?i ?multifield) " " (nth$ ?j ?multifield) crlf)
(if (> (nth$ ?i ?multifield) (nth$ ?j ?multifield)) then
(printout t "> " (nth$ ?i ?multifield) " " (nth$ ?j ?multifield) crlf)
(bind ?temp (nth$ ?i ?multifield))
(bind ?multifield (replace$ ?multifield ?i ?i (nth$ ?j ?multifield)))
(bind ?multifield (replace$ ?multifield ?j ?j ?temp))
; or you can do the two above replacements in one call
; (bind ?multifield (replace$ (replace$ ?multifield ?i ?i (nth$ ?j ?multifield)) ?j ?j ?temp))
(printout t "> que" (nth$ ?i ?multifield) " " (nth$ ?j ?multifield) crlf)
)
)
)
(return ?multifield)
)