Reputation: 505
In my program I have the following situation:
Template:
(deftemplate MAIN::travel-banchmark
(slot name)
(slot value)
)
Facts:
(travel-banchmark (name location) (value torino))
(travel-banchmark (name location) (value roma))
(travel-banchmark (name location) (value milano))
(travel-banchmark (name location) (value venezia))
I have to create (with a rule) all the possible subset of, as an example, k=3
(n.b., k
is a variable) location (k-combination) and for every subset I have to permute the elements inside it (and assert
every permutation).
Example combination:
torino roma milano
torino roma venezia
roma milano venezia
venezia milano torino
Example permutation:
torino roma milano -> roma torino milano -> torino milano roma ...
I'm wondering if there is something that can I do in the LHS of the rule in order to avoid writing all the logic in the RHS?
Any suggestion of useful syntax that can I use?
Upvotes: 1
Views: 435
Reputation: 10757
Here's one way to do it using rules:
CLIPS (6.31 6/12/19)
CLIPS>
(deftemplate travel-banchmark
(slot name)
(slot value))
CLIPS>
(deftemplate permutation
(multislot values))
CLIPS>
(deffacts initial
(k-combination 3)
(travel-banchmark (name location) (value torino))
(travel-banchmark (name location) (value roma))
(travel-banchmark (name location) (value milano))
(travel-banchmark (name location) (value venezia)))
CLIPS>
(defrule first-in-permutation
(k-combination ~0)
(travel-banchmark (name location) (value ?city))
=>
(assert (permutation (values ?city))))
CLIPS>
(defrule next-in-permutation
(k-combination ?k)
?p <- (permutation (values $?cities))
(test (< (length$ ?cities) ?k))
(travel-banchmark (name location) (value ?city))
(test (not (member$ ?city ?cities)))
=>
(assert (permutation (values ?cities ?city))))
CLIPS>
(defrule cleanup
(declare (salience -5))
(k-combination ?k)
?p <- (permutation (values $?cities))
(test (< (length$ ?cities) ?k))
=>
(retract ?p))
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0 (initial-fact)
f-1 (k-combination 3)
f-2 (travel-banchmark (name location) (value torino))
f-3 (travel-banchmark (name location) (value roma))
f-4 (travel-banchmark (name location) (value milano))
f-5 (travel-banchmark (name location) (value venezia))
f-8 (permutation (values venezia milano roma))
f-9 (permutation (values venezia milano torino))
f-11 (permutation (values venezia roma milano))
f-12 (permutation (values venezia roma torino))
f-14 (permutation (values venezia torino milano))
f-15 (permutation (values venezia torino roma))
f-18 (permutation (values milano venezia roma))
f-19 (permutation (values milano venezia torino))
f-21 (permutation (values milano roma venezia))
f-22 (permutation (values milano roma torino))
f-24 (permutation (values milano torino venezia))
f-25 (permutation (values milano torino roma))
f-28 (permutation (values roma venezia milano))
f-29 (permutation (values roma venezia torino))
f-31 (permutation (values roma milano venezia))
f-32 (permutation (values roma milano torino))
f-34 (permutation (values roma torino venezia))
f-35 (permutation (values roma torino milano))
f-38 (permutation (values torino venezia milano))
f-39 (permutation (values torino venezia roma))
f-41 (permutation (values torino milano venezia))
f-42 (permutation (values torino milano roma))
f-44 (permutation (values torino roma venezia))
f-45 (permutation (values torino roma milano))
For a total of 30 facts.
CLIPS>
For comparison, generating the permutations using a function:
CLIPS> (clear)
CLIPS>
(deftemplate travel-banchmark
(slot name)
(slot value))
CLIPS>
(deftemplate permutation
(multislot values))
CLIPS>
(deffacts initial
(k-combination 3)
(travel-banchmark (name location) (value torino))
(travel-banchmark (name location) (value roma))
(travel-banchmark (name location) (value milano))
(travel-banchmark (name location) (value venezia)))
CLIPS>
(deffunction gen-permutation (?k ?cities $?result)
(if (= ?k 0)
then
(assert (permutation (values ?result)))
(return))
(foreach ?c ?cities
(gen-permutation (- ?k 1) (delete-member$ ?cities ?c) ?result ?c)))
CLIPS>
(defrule generate
(k-combination ?k)
=>
(bind ?cities (create$))
(do-for-all-facts ((?tb travel-banchmark)) (eq ?tb:name location)
(bind ?cities (create$ ?cities ?tb:value)))
(gen-permutation ?k ?cities))
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0 (initial-fact)
f-1 (k-combination 3)
f-2 (travel-banchmark (name location) (value torino))
f-3 (travel-banchmark (name location) (value roma))
f-4 (travel-banchmark (name location) (value milano))
f-5 (travel-banchmark (name location) (value venezia))
f-6 (permutation (values torino roma milano))
f-7 (permutation (values torino roma venezia))
f-8 (permutation (values torino milano roma))
f-9 (permutation (values torino milano venezia))
f-10 (permutation (values torino venezia roma))
f-11 (permutation (values torino venezia milano))
f-12 (permutation (values roma torino milano))
f-13 (permutation (values roma torino venezia))
f-14 (permutation (values roma milano torino))
f-15 (permutation (values roma milano venezia))
f-16 (permutation (values roma venezia torino))
f-17 (permutation (values roma venezia milano))
f-18 (permutation (values milano torino roma))
f-19 (permutation (values milano torino venezia))
f-20 (permutation (values milano roma torino))
f-21 (permutation (values milano roma venezia))
f-22 (permutation (values milano venezia torino))
f-23 (permutation (values milano venezia roma))
f-24 (permutation (values venezia torino roma))
f-25 (permutation (values venezia torino milano))
f-26 (permutation (values venezia roma torino))
f-27 (permutation (values venezia roma milano))
f-28 (permutation (values venezia milano torino))
f-29 (permutation (values venezia milano roma))
For a total of 30 facts.
CLIPS>
Upvotes: 2