First CLIPS code doesnt work - system

I wrote my first CLIPS code for a school project but I am not familiar with CLIPS (I use C# and python as main languages).
This is my code and the errors I am gettin:
(defrule determine-closing-date
(not (day-to-close ?))
(billing-size ?)
(unpaid-invoices-number ?)
=>
(if
(or
(< billing-size 1000000)
(< unpaid-invoices-number 1000000)
)
then (assert (day-to-close MtTh))
else (assert (day-to-close friday))
)
(defrule determine-billing-size ""
(not (billing-size ?))
(not (day-to-close ?))
=>
(printout t "¿Cuál es el tamaño de la facturacion?")
(assert (billing-size ?size (read))))
(defrule determine-unpaid-invoices-number ""
(not (unpaid-invoices-number ?))
(not (day-to-close ?))
=>
(printout t "¿Cuál es la cantidad de facturas no pagadas")
(assert (unpaid-invoices-number ?size (read))))
(defrule determine-friday-load ""
(day-to-close friday)
(not (friday-load ?))
=>
(printout t "¿Cuál es la carga de cierres para el viernes?")
(assert (friday-load ?load (read))))
(defrule determine-saturday-closing ""
(day-to-close friday)
(not(< friday-load 1000000))
=>
(assert (day-to-close saturday)))
(defrule day-to-close-conclulssion ""
(day-to-close ?)
=>
(if (eq day-to-close MtTh)
then (printout t "Se puede cerrar de Lunes a Jueves")
else (
if (eq day-to-close friday)
then (printout t "Se debe cerrar viernes.")
else (printout t "Se debe cerrar sabado.")
)
))
The errores are:
[ARGACCES5] Function < expected argument #1 to be of type integer or float
[PRCCODE3] Undefined variable size referenced in RHS of defrule.
[CSTRCPSR1] WARNING: Redefining defrule: determine-saturday-closing +j+j+j
[CSTRCPSR1] WARNING: Redefining defrule: day-to-close-conclulssion +j+j

Some suggest revisions:
(defrule determine-closing-date
(not (day-to-close ?))
(billing-size ?billing-size)
(unpaid-invoices-number ?unpaid-invoices-number)
=>
(if (or (< ?billing-size 1000000)
(< ?unpaid-invoices-number 1000000))
then (assert (day-to-close MtTh))
else (assert (day-to-close friday))))
(defrule determine-billing-size ""
(not (billing-size ?))
(not (day-to-close ?))
=>
; What is the size of the billing?
(printout t "¿Cuál es el tamaño de la facturacion? ")
(bind ?size (read))
(assert (billing-size ?size)))
(defrule determine-unpaid-invoices-number ""
(not (unpaid-invoices-number ?))
(not (day-to-close ?))
=>
; What is the amount of unpaid bills?
(printout t "¿Cuál es la cantidad de facturas no pagadas? ")
(bind ?size (read))
(assert (unpaid-invoices-number ?size)))
(defrule determine-friday-load ""
(day-to-close friday)
(not (friday-load ?))
=>
; What is the burden of closures for Friday?
(printout t "¿Cuál es la carga de cierres para el viernes? ")
(bind ?load (read))
(assert (friday-load ?load)))
(defrule determine-saturday-closing ""
?dtc <- (day-to-close friday)
(friday-load ?load&:(< ?load 1000000))
=>
(retract ?dtc)
(assert (day-to-close saturday)))
(defrule day-to-close-conclusion ""
(declare (salience -10))
(day-to-close ?day-to-close)
=>
(switch ?day-to-close
(case MtTh
; Can be closed from Monday to Thursday.
then (printout t "Se puede cerrar de Lunes a Jueves." crlf))
(case friday
; Must be closed Fridays.
then (printout t "Se debe cerrar viernes." crlf))
(default
; Must be closed Saturday.
then (printout t "Se debe cerrar sabado." crlf))))
And the output it produces:
CLIPS> Loading Buffer...
******
CLIPS> (reset)
CLIPS> (run)
¿Cuál es el tamaño de la facturacion? 10
¿Cuál es la cantidad de facturas no pagadas? 10
Se puede cerrar de Lunes a Jueves.
CLIPS> (reset)
CLIPS> (run)
¿Cuál es el tamaño de la facturacion? 3000000
¿Cuál es la cantidad de facturas no pagadas? 3000000
¿Cuál es la carga de cierres para el viernes? 10
Se debe cerrar sabado.
CLIPS> (reset)
CLIPS> (run)
¿Cuál es el tamaño de la facturacion? 3000000
¿Cuál es la cantidad de facturas no pagadas? 3000000
¿Cuál es la carga de cierres para el viernes? 3000000
Se debe cerrar viernes.
CLIPS>

Related

Clips not printing anything

I tried to write the following code in CLIPS for a school project (even though I don't understand why AI is done in this language):
(deftemplate blood
(slot bt)
(multislot acc))
(deffacts acceptance
(blood (bt 0) (acc 0 0))
(blood (bt A) (acc 0 A))
(blood (bt B) (acc 0 B))
(blood (bt AB) (acc 0 A B AB)))
(defrule reading-input
=>
(printout t "Bloodtype of patient? ")
(assert (patient (read)))
(printout t "Bloodtype of donor? ")
(assert (donor (read))))
(defrule check-acceptance
(patient ?patient)
(donor ?donor)
(blood (bt ?bt1) (acc ?acc1))
(test (member$ ?donor ?acc1))
=>
(printout t "Transfusion is safe" crlf))
For some reason it wouldn't print anything for inputs A and A or anything else. I also tried this with a if then else statement, but same result.
[prev code]
(blood (bt ?bt1) (acc ?acc1))
=>
(if (eq ?patient ?bt1)
then
(printout t ?bt1)
else
(printout t ?donor)))
The idea is to write a program that prints whether blood transfusion is safe or not.
Modify your blood pattern so that the bt slot is restricted to the blood type of the patient and change the variable acc1 to a multifield variable so that it will bind to all of the values in the acc slot:
(defrule check-acceptance
(patient ?patient)
(donor ?donor)
(blood (bt ?patient) (acc $?acc1))
(test (member$ ?donor ?acc1))
=>
(printout t "Transfusion is safe" crlf))

Something like OR operator in CLIPS (CLIPS Rule Based Programming Language)

I need help with this program, I couldn't find out how to do that a user can input a yes/no for characters and I have defined a type of animal-like mammal - for mammal applies that milk character must be yes and legs(number of legs) can be 2 or 4 and another character can be yes or no like for example -
mammal - milk yes, legs 2 or 4, but backbone can yes or no, predator yes or no .... but I don't know how to do it (OR condition or idk something like that), user can input one of these its find out the type of animal which is defined in effects, thanks for help :)
;*********** DEFTEMPLATE ***********;
(deftemplate animal_type
(slot type (type SYMBOL) (allowed-symbols mammal bird fish))
(slot milk (type SYMBOL) (allowed-symbols yes no))
(slot feathers (type SYMBOL) (allowed-symbols yes no))
(slot fins (type SYMBOL) (allowed-symbols yes no))
(slot backbone (type SYMBOL) (allowed-symbols yes no))
(slot fly (type SYMBOL) (allowed-symbols yes no))
(slot predator (type SYMBOL) (allowed-symbols yes no))
(multislot legs (type INTEGER) (allowed-integers 0 2 4 6 8))
)
(deftemplate finding_type
(slot milk (type SYMBOL) (allowed-symbols yes no))
(slot feathers (type SYMBOL) (allowed-symbols yes no))
(slot fins (type SYMBOL) (allowed-symbols yes no))
(slot backbone (type SYMBOL) (allowed-symbols yes no))
(slot fly (type SYMBOL) (allowed-symbols yes no))
(slot predator (type SYMBOL) (allowed-symbols yes no))
(multislot legs (type INTEGER) (allowed-integers 0 2 4 6 8))
)
;*********** DEFFACTS ***********;
(deffacts characters_type
(animal_type (typ mammal) (milk yes) (legs 2 4))
(animal_type (typ bird) (milk no) (feathers yes) (fly yes))
(animal_type (typ fish) (milk no) (feathers no) (fins yes) (legs 0))
)     
;something like this (animal_type (typ mammal) (milk yes) (backbone or(yes no)) ... (legs 2 4))
(deffacts temp_fact
(next_search)
)
(defrule input_characters
?gone<-(next_search)
=> (retract ?gone)
(printout t " " crlf)
(printout t "Enter - yes/no, legs - 0/2/4/6/8" crlf)
(printout t "==================================================================" crlf)
(printout t "Milk:")
(bind ?o1 (read))
(printout t "Feathers:")
(bind ?o2 (read))
(printout t "Fins:")
(bind ?o3 (read))
(printout t "Backbone:")
(bind ?o4 (read))
(printout t "Fly:")
(bind ?o5 (read))
(printout t "Predator:")
(bind ?o6 (read))
(printout t "Legs:")
(bind ?o7 (read))
(assert (finding_type (milk ?o1) (feathers ?o2) (fins ?o3) (backbone ?o4) (fly ?o5) (predator ?o6) (legs ?o7)) )
)
(defrule find_out_type
(finding_type (milk ?o1) (feathers ?o2) (fins ?o3) (backbone ?o4) (fly ?o5) (predator ?o6) (legs ?o7))
(animal_type (type ?type) (milk ?o1) (feathers ?o2) (fins ?o3) (backbone ?o4) (fly ?o5) (predator ?o6) (legs ?o7))
=>
(printout t " " crlf)
(printout t "Type of animal is: " ?type crlf)
)
(defrule not_found
(finding_type (milk ?o1) (feathers ?o2) (fins ?o3) (backbone ?o4) (fly ?o5) (predator ?o6) (legs ?o7))
(not (animal_type (type ?type) (milk ?o1) (feathers ?o2) (fins ?o3) (backbone ?o4) (fly ?o5) (predator ?o6) (legs ?o7)) )
=>
(printout t " " crlf)
(printout t "Nothing found!" crlf)
)
(defrule cancel (declare (salience -10))
?gone<-(finding_type (milk ?o1) (feathers ?o2) (fins ?o3) (backbone ?o4) (fly ?o5) (predator ?o6) (legs ?o7))
=>
(retract ?gone)
)
Modify the animal_type pattern in your rules to use multifield wildcards to match extraneous values to the left and right of the specified number of legs. As your rules are currently the animal_type patterns will only be matched by facts containing exactly one value in the legs slot.
(animal_type (type ?type)
(milk ?o1)
(feathers ?o2)
(fins ?o3)
(backbone ?o4)
(fly ?o5)
(predator ?o6)
(legs $? ?o7 $?))

Determining the number of turtle-clusters

I have been trying to calculate the number of turtle-clusters in my World but I have been constantly faced with "You can't use GROUPE in a patch context, because GROUPE is turtle-only". I am using bits from the Segregation model of Schelling and adapting the Patch Clusters Example from the Model Library, but I have not been able to get the number of clusters by using the command show max [amas] of personnes after running the model.
The line causing problems is towards the bottom of the bloc and is:
(groupe = [groupe] of myself)]
Here is the full code:
extensions
[
GIS ; Extension GIS
]
globals
[
v
;vc
routes.data ; shapefile routes
Usol.data ; shapefile utilisation sol
average-happy ; pourcentage heureux
amas
]
patches-own
[
routes ; routes
routes? ; booléenne routes
Usol
Usol?
state ; état d'une patch
val ; valeur
cluster
]
turtles-own
[
groupe
unhappy?
counter
similar-nearby
other-nearby
total-nearby
happy
]
breed ; Création d'une classe
[
personnes
personne
]
to setup ; Déclaration de la procédure setup
ca ; Clear-all
reset-ticks ; Remet le compteur de ticks à zéro
set v 2
initialiserGIS ; Initialisation de la procédure initialiserGIS
creerHumains
do-plots
end ; Fin de la procédure setup
to initialiserGIS ; Déclaration de la procédure initialiserGIS
set Usol.data gis:load-dataset "utilisationDuSol.shp"
gis:apply-coverage Usol.data "LANDUSE" Usol
ask patches
[
set Usol? FALSE
]
ask patches gis:intersecting Usol.data
[
set Usol? TRUE
ifelse Usol = "residential"
[
set state 1
set pcolor green
]
[
set state 0
set pcolor grey
]
]
set routes.data gis:load-dataset "routesMtl.shp"
ask patches
[
set routes? FALSE
]
ask patches gis:intersecting routes.data
[
set routes? TRUE
set state 0 ; Empêche aux agents d'habiter sur les routes
set pcolor red ; Assigne la couleur rouge aux routes
]
end ; Fin de la procédure initialiser GIS
to creerHumains ; Déclaration de la procédure creerHumains
ask patches with [state = 1] ; Demande aux cellules résidentielles
[
set val random-float 1 ; Accorde une valeur aléatoire décimale entre 0 et 1 à la variable val
]
let vide 0.1 ; Initialisation de la variable locale vide avec la valeur 0.1
let limite1 (1 - vide) / v ; Initialisation de la variable locale limite
let residents patches with [state = 1 and val > vide] ; Initialisation de la variable locale residents
ask residents ; Demande aux residents
[
sprout-personnes 1 ; Primitive permettant à une patch de créer un agent sur toutes les patches résidentielles
] ; Permet de créer un nombre identique de personne de chaque groupe
let limiteList (list (pmin * (1 - vide )) ((1 - pmin) * (1 - vide)))
let i 0
let minVal vide
let maxVal 0
while [i <= v - 1]
[
set maxVal minVal + item i limiteList
ask personnes with [val <= maxVal and val > minVal]
[
set groupe i + 1
]
set minVal maxVal
set i i + 1
]
ask personnes ;ceci sert uniquement à attribuer une couleur différente à chaque groupe
[ ; Assigne la couleur et la forme appropriée en fonction du groupe
ifelse groupe = 1
[
set color red
set shape "house"
]
[
ifelse groupe = 2
[
set color blue
set shape "house"
]
[
ifelse groupe = 3
[
set color green
set shape "house"
]
[
ifelse groupe = 4
[
set color orange
set shape "house"
]
[
ifelse groupe = 5
[
set color black
set shape "house"
]
[
ifelse groupe = 6
[
set color brown
set shape "house"
]
[
ifelse groupe = 7
[
set color pink
set shape "house"
]
[
ifelse groupe = 8
[
set color white
set shape "house"
]
[
set color magenta
set shape "house"
]
]
]
]
]
]
]
]
]
end ; Fin de la procédure creerHumains
to move ; Déclaration de la procédure move
move-to one-of patches with [Usol = "residential"]
if any? other turtles-here
[
move ;; Continue jusqu'à tant qu'une patch soit trouvée
]
end
to update-variables ; Déclaration de la procédure update-variables ; permet de mettre à jour les valeurs
update-turtles
update-globals
end ; Fin de la procédure update-variables
to update-turtles ; Déclaration de la procédure update-turtles
ask turtles ; demande turtles
[ ; Test des patches voisines
set counter 0 ; réinitialise counter
set similar-nearby count (turtles-on neighbors) with [groupe = [groupe] of myself]
set other-nearby count (turtles-on neighbors) with [groupe != [groupe] of myself]
set total-nearby similar-nearby + other-nearby
ifelse groupe = 1
[
ifelse (Tmin >= similar-nearby) ; vérification si vc est supérieur ou égale aux voisins similaires
[ ; personne unhappy + move
set unhappy? TRUE
set happy 0
move
]
[ ; personne happy
set unhappy? FALSE
set happy 1
]
]
[
ifelse (Tmaj <= similar-nearby) ; vérification si vc est supérieur ou égale aux voisins similaires
[ ; personne unhappy + move
set unhappy? TRUE
set happy 0
move
]
[ ; personne happy
set unhappy? FALSE
set happy 1
]
]
]
end ; Fin de la procédure update-turtles
to update-globals ; Déclaration de la procédure update-globals
set average-happy mean [happy] of turtles ; Average-happy = moyenne des turtles happy
end ; Fin de la procédure update-globals
to go ; Déclaration de la procédure go
update-variables ; Vérifie l'état de chacunes des personnes et fait bouger celles nécessitant de l'être
tick ; Incrémente la valeur de la variable tick
if ticks >= 100 ; Si le nombre de ticks est supérieur ou égal à 100
[
stop ; Arrête le modèle
]
if c-unhappy = 0
[
stop ; Arrête le modèle si personne est unhappy
]
end ; Fin de la procédure go
to do-plots ; Déclaration de la procédure do-plots
plot average-happy * 100 ; Plot la moyenne des habitants étant happy
end ; Fin de la procédure do-plots
to-report c-happy ; Déclaration de la procédure de rapportage c-happy
report sum [happy] of turtles ; Rapporte le nombre de turtles étant happy
end ; Fin de la procédure de rapportage c-happy
to-report c-unhappy ; Déclaration de la procédure de rapportage c-unhappy
report ((count turtles) - (sum [happy] of turtles)) ; Rapporte le nombre de turtles étant unhappy
end ; Fin de la procédure de rapportage c-unhappy
;;; Q6
to find-clusters
loop
[
;; pick a random patch that isn't in a cluster yet
let seed one-of personnes with [cluster = nobody]
;; if we can't find one, then we're done!
if seed = nobody
[
show-clusters
stop
]
;; otherwise, make the patch the "leader" of a new cluster
;; by assigning itself to its own cluster, then call
;; grow-cluster to find the rest of the cluster
ask seed
[
set cluster self
grow-cluster
]
]
display
end
to grow-cluster ;; patch procedure
ask neighbors4 with [(cluster = nobody) and
(groupe = [groupe] of myself)]
[
set cluster [cluster] of myself
grow-cluster
]
end
;; once all the clusters have been found, this is called
;; to put numeric labels on them so the user can see
;; that the clusters were identified correctly
to show-clusters
let counter2 0
loop
[ ;; pick a random patch we haven't labeled yet
let p one-of patches with [plabel = ""]
if p = nobody
[
stop
]
;; give all patches in the chosen patch's cluster
;; the same label
ask p
[
ask personnes with [cluster = [cluster] of myself]
[
set amas counter2
]
]
set counter2 counter2 + 1
]
end

Eight Queens Puzzle in CLIPS

I'm trying to develop an solver for the eight queens problem (https://en.wikipedia.org/wiki/Eight_queens_puzzle) in CLIPS, but I'm a newbie in this language.
First of all, I was trying to make a rule to verify a new assertion comparing column/line of previous assertions. Its working when is inserted a duplicated line, however when inserted a duplicated column, it doesn't detect it. What's wrong with this code?
(defrule verificaAssercaoDamas ; verifica se atende as regras
?novaPosicao <- (d ?line ?column)
?posicao <- (d ?line2 ?column2)
(test (neq ?posicao ?novaPosicao))
(test (or (eq ?line2 ?line) (eq ?column column2)) )
=>
(retract ?novaPosicao)
(if (< (+ ?column 1) 9)
then (assert (d ?line (+ ?column 1) ))
)
CLIPS> (assert(d 0 0))
<Fact-1>
CLIPS> (assert(d 1 0))
<Fact-2>
CLIPS> (assert(d 0 1))
<Fact-3>
CLIPS> (agenda)
0 cerificaAssercaoDamas: f-3, f-1
0 cerificaAssercaoDamas: f-1, f-3
For a total of 2 activations.
CLIPS>
You're using the expression (eq ?column column2) which is comparing the variable ?column to the symbol column2. You need to compare it to the variable ?column2.
CLIPS> (clear)
CLIPS>
(defrule verificaAssercaoDamas
?novaPosicao <- (d ?line ?column)
?posicao <- (d ?line2 ?column2)
(test (neq ?posicao ?novaPosicao))
(test (or (eq ?line2 ?line) (eq ?column ?column2)))
=>
(retract ?novaPosicao)
(if (< (+ ?column 1) 9)
then (assert (d ?line (+ ?column 1)))))
CLIPS> (assert (d 0 0))
<Fact-1>
CLIPS> (assert (d 1 0))
<Fact-2>
CLIPS> (assert (d 0 1))
<Fact-3>
CLIPS> (agenda)
0 verificaAssercaoDamas: f-3,f-1
0 verificaAssercaoDamas: f-1,f-3
0 verificaAssercaoDamas: f-2,f-1
0 verificaAssercaoDamas: f-1,f-2
For a total of 4 activations.
CLIPS>
If you're testing equality/inequality of numbers, you should use the = and != (or <>) functions as these will throw errors for non-numeric arguments:
CLIPS> (clear)
CLIPS>
(defrule verificaAssercaoDamas
?novaPosicao <- (d ?line ?column)
?posicao <- (d ?line2 ?column2)
(test (neq ?posicao ?novaPosicao))
(test (or (= ?line2 ?line) (= ?column column2)))
=>
(retract ?novaPosicao)
(if (< (+ ?column 1) 9)
then (assert (d ?line (+ ?column 1)))))
[ARGACCES5] Function = expected argument #2 to be of type integer or float
ERROR:
(defrule MAIN::verificaAssercaoDamas
?novaPosicao <- (d ?line ?column)
?posicao <- (d ?line2 ?column2)
(test (neq ?posicao ?novaPosicao))
(test (or (= ?line2 ?line) (= ?column column2)
CLIPS>
You can also remove the duplicate activations by checking that the fact index of ?novaPosicao is greater than the one for ?posicao:
CLIPS> (clear)
CLIPS>
(defrule verificaAssercaoDamas
?novaPosicao <- (d ?line ?column)
?posicao <- (d ?line2 ?column2)
(test (< (fact-index ?posicao) (fact-index ?novaPosicao)))
(test (or (= ?line2 ?line) (= ?column ?column2)))
=>
(retract ?novaPosicao)
(if (< (+ ?column 1) 9)
then (assert (d ?line (+ ?column 1)))))
CLIPS> (assert (d 0 0))
<Fact-1>
CLIPS> (assert (d 1 0))
<Fact-2>
CLIPS> (assert (d 0 1))
<Fact-3>
CLIPS> (agenda)
0 verificaAssercaoDamas: f-3,f-1
0 verificaAssercaoDamas: f-2,f-1
For a total of 2 activations.
CLIPS>

CLIPS: slots within multislots

I am currently working in CLIPS and I am new to it. I am trying to replicate the following information in a CLIPS deftemplate:
[Person, [Class,Class],[[M 9,11],[F,9,11]]]
It has a person, multiple classes that they can take and the times that they can take the class. I try to replicate this information in the following deftemplate:
(deftemplate person
(slot Name)
(multislot Class)
(multislot Available))
My problem is I do not understand what I am supposed to do in the available multislot because it has three inputs. Is there a way that I can make slots within a multislot? I have looked online for ways to do this but have not been able to correctly solve this problem.
Here are four different approaches. I would suggest something similar to approach 3 or 4 since these involve simple linkages between facts/instances.
CLIPS> (clear) ; Approach 1
CLIPS>
(deftemplate person
(slot Name)
(multislot Class)
(multislot Available))
CLIPS>
(deffacts people
(person (Name Frank)
(Class Biology Calculus)
(Available M 9 11 F 9 11)))
CLIPS>
(deffunction #-of-triplets (?mf)
(div (length$ ?mf) 3))
CLIPS>
(deffunction nth-triplet (?mf ?n)
(subseq$ ?mf (+ 1 (* (- ?n 1) 3))(* ?n 3)))
CLIPS>
(defrule print-availability
(person (Name ?name)
(Available $?a))
=>
(loop-for-count (?i (#-of-triplets ?a))
(bind ?triplet (nth-triplet ?a ?i))
(bind ?d (nth$ 1 ?triplet))
(bind ?b (nth$ 2 ?triplet))
(bind ?e (nth$ 3 ?triplet))
(printout t ?name " " ?d " " ?b " " ?e crlf)))
CLIPS> (reset)
CLIPS> (run)
Frank M 9 11
Frank F 9 11
CLIPS> (clear) ; Approach 2
CLIPS>
(deftemplate person
(slot Name)
(multislot Class)
(multislot Available-Weekday)
(multislot Available-Begin)
(multislot Available-End))
CLIPS>
(deffacts people
(person (Name Frank)
(Class Biology Calculus)
(Available-Weekday M F)
(Available-Begin 9 9)
(Available-End 11 11)))
CLIPS>
(defrule print-availability
(person (Name ?name)
(Available-Weekday $?f1 ?d $?)
(Available-Begin $?f2 ?b $?)
(Available-End $?f3 ?e $?))
(test (= (length$ ?f1)
(length$ ?f2)
(length$ ?f3)))
=>
(printout t ?name " " ?d " " ?b " " ?e crlf))
CLIPS> (reset)
CLIPS> (run)
Frank M 9 11
Frank F 9 11
CLIPS> (clear) ; Approach 3
CLIPS>
(deftemplate person
(slot Name)
(slot ID)
(multislot Class))
CLIPS>
(deftemplate availability
(slot owner-ID)
(slot Weekday)
(slot Begin)
(slot End))
CLIPS>
(deffacts information
(person (Name Frank) (ID 1)
(Class Biology Calculus))
(availability (owner-ID 1) (Weekday M) (Begin 9) (End 11))
(availability (owner-ID 1) (Weekday F) (Begin 9) (End 11)))
CLIPS>
(defrule print-availability
(person (Name ?name) (ID ?id))
(availability (owner-ID ?id) (Weekday ?d) (Begin ?b) (End ?e))
=>
(printout t ?name " " ?d " " ?b " " ?e crlf))
CLIPS> (reset)
CLIPS> (run)
Frank F 9 11
Frank M 9 11
CLIPS> (clear) ; Approach 4
CLIPS>
(defclass PERSON
(is-a USER)
(slot Name)
(multislot Class)
(multislot Available))
CLIPS>
(defclass AVAILABILITY
(is-a USER)
(slot Weekday)
(slot Begin)
(slot End))
CLIPS>
(definstances information
(of PERSON (Name Frank)
(Class Biology Calculus)
(Available (make-instance of AVAILABILITY (Weekday M) (Begin 9) (End 11))
(make-instance of AVAILABILITY (Weekday F) (Begin 9) (End 11)))))
CLIPS>
(defrule print-availability
(object (is-a PERSON) (Name ?name) (Available $? ?a $?))
(object (is-a AVAILABILITY) (name ?a))
=>
(printout t ?name " " (send ?a get-Weekday)
" " (send ?a get-Begin)
" " (send ?a get-End) crlf)))
CLIPS> (reset)
CLIPS> (run)
Frank F 9 11
Frank M 9 11
CLIPS>