Access a slot from multifield in deffunction - expert-system

I have this function which calculates some value based on multiple slots of multiple multifield facts.
Because quite some slots are involved and all of them are needed in the function I was thinking if I could pass a whole fact to a function and access its slots in it,
like so:
(deftemplate a-fact
(slot id)
(slot name)
(slot ...)
...
)
(deffunction a-funciton (?factadr)
(switch ?factadr:name
(case bla then ...)
)
(return ?calculated-value)
)
(defrule a-rule
?factadr <- (a-fact (id ?i))
=>
(if (> **(a-function ?factadr) 20) then ... )
)
I saw this ?fact-adrres:slot-name in this example and thought it will work but it doesn't. So, is it possible and how to do it?
(bind ?facts (find-all-facts ((?f attribute))
(and (eq ?f:name wine)
(>= ?f:certainty 20))))
Clips 6.3 is used.

Use the fact-slot-value function.
CLIPS>
(deftemplate a-fact
(slot id)
(slot name))
CLIPS>
(defrule a-rule
?f <- (a-fact)
=>
(printout t (fact-slot-value ?f id) " " (fact-slot-value ?f name) crlf))
CLIPS> (assert (a-fact (id 3) (name x)))
<Fact-1>
CLIPS> (assert (a-fact (id 7) (name y)))
<Fact-2>
CLIPS> (run)
7 y
3 x
CLIPS>

Related

Clips Beginner: How to assign two variables to one template slot value without using multislot in pyclips

I want to insert two variable values in a string slot of a template but I am having errors. I know about the multislot but it is giving me a dictionary output like this:
('1.', '§ 2 is amended as follows:')
But I want like this:
1. § 2 is amended as follows:
https://www.csee.umbc.edu/portal/clips/usersguide/ug4.html In this link it is written that we can assign many variables to one slot in assert but when I do this I am getting errors. I am importing clips in python in VSCode. Thank you in advance and I hope I am explaining the issue properly.
These are the rules:
(defrule createlist1
(declare (salience 91))
(ROW (counter ?A)
(ID ?id)
(Text ?t)
(Path "//Document/Sect[3]/Sect/L/LI/Lbl"))
=>
(assert (Temp (tempvalue "YES")
(temptext ?t))))
(defrule createlist2
(declare (salience 91))
(and (Temp (tempvalue "YES")
(temptext ?t))
(ROW (counter ?A)
(ID ?id)
(Text ?text)
(Path "//Document/Sect[3]/Sect/L/LI/LBody/ParagraphSpan")))
=>
(printout t " value is " ?t ?text crlf)
(assert (WordPR (counter ?A)
(structure ?id)
(tag "list")
(style "list")
(text ?t ?text))))
These are the templates:
template_WordPR = """
(deftemplate WordPR
(slot counter (type INTEGER))
(slot structure (type INTEGER))
(slot tag (type STRING))
(slot style (type STRING))
(slot text (type STRING)))
"""
template_temporary = """
(deftemplate Temp
(slot tempvalue (type STRING))
(slot temptext (type STRING)))
"""
template_string = """
(deftemplate ROW
(slot counter (type INTEGER))
(slot ID (type INTEGER))
(slot Text (type STRING))
(slot Path (type STRING)))
"""
This is the error I am getting:
ERROR: The single field slot 'text' can only contain a single field value.
You can't put multiple values into a slot without declaring it as a multislot, but if you're dealing with strings you can concatenate the values before assigning them to the slot.
CLIPS>
(deftemplate WordPR
(slot counter (type INTEGER))
(slot structure (type INTEGER))
(slot tag (type STRING))
(slot style (type STRING))
(slot text (type STRING)))
CLIPS>
(deftemplate Temp
(slot tempvalue (type STRING))
(slot temptext (type STRING)))
CLIPS>
(deftemplate ROW
(slot counter (type INTEGER))
(slot ID (type INTEGER))
(slot Text (type STRING))
(slot Path (type STRING)))
CLIPS>
(deffacts start
(Temp (tempvalue "YES")
(temptext "1."))
(ROW (Text "§ 2 is amended as follows:")))
CLIPS>
(defrule createlist2
(declare (salience 91))
(Temp (tempvalue "YES")
(temptext ?t))
(ROW (counter ?A)
(ID ?id)
(Text ?text))
=>
(assert (WordPR (counter ?A)
(structure ?id)
(tag "list")
(style "list")
(text (str-cat ?t " " ?text)))))
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-1 (Temp (tempvalue "YES") (temptext "1."))
f-2 (ROW (counter 0) (ID 0) (Text "§ 2 is amended as follows:") (Path ""))
f-3 (WordPR (counter 0) (structure 0) (tag "list") (style "list") (text "1. § 2 is amended as follows:"))
For a total of 3 facts.
CLIPS>

Jess: Error with Operator less than

I am learning about less and have a problem when define a rule with the less than operator '<.
This are my defTemplates:
(deftemplate AgudezaVisual
(slot agudezaVisual)
(slot estado)
)
(deftemplate Bucodental
(slot hayDientesDañados)
(slot hayDientesConConcavidades)
(slot hayCaries)
(slot estadoEncias)
(slot presentaCancerOral)
(slot haySangradoOInflamacionPaladar)
(slot haySangradoOInflamacionLengua)
(slot tieneGengivitis)
(slot estado)
)
(deftemplate Respiratorio
(slot tieneDisnea)
(slot tieneTos)
(slot tieneEsputo)
(slot tieneDolorToracico)
(slot tieneEdema)
(slot tieneJadeo)
(slot estado)
)
(deftemplate Digestivo
(slot tieneCirrosis)
(slot esCeliaco)
(slot esDiabetico)
(slot tieneHepatitisB)
(slot tieneHepatitisC)
(slot estado)
)
(deftemplate Electrocardiograma
(slot frecuenciaCardiaca)
(slot tieneInsuficienciaCardiaca)
(slot tieneArritmia)
(slot tienePericarditis)
(slot tieneMiocarditis)
(slot estado)
)
(deftemplate Hemograma
(slot eritrocitos)
(slot hematocrito)
(slot hemoglobina)
(slot leucocitos)
(slot plaquetas)
(slot estado)
)
(deftemplate Eritrocedimentacion
(slot velocidad)
(slot posibleAnemia)
(slot posibleInfecciosas)
(slot posibleEnfermedadesInflamatorias)
(slot posiblesEnfermedadesReumaticas)
(slot estado)
)
(deftemplate Glucemia
(slot glocosa)
(slot estado)
)
(deftemplate Uremia
(slot urea)
(slot estado)
)
(deftemplate Orina
(slot leucocitos)
(slot cetonas)
(slot sangre)
(slot ph)
(slot bilirrubina)
(slot nitritos)
(slot estado)
)
(deftemplate RadiografiaTorax
(slot presentaElementosPatologicos)
(slot estado)
)
(deftemplate InformeFinalAptitud
(slot observaciones)
(slot estado)
)
And this my rules:
(defrule R1
(AgudezaVisual (agudezaVisual ?a & : (> ?a 0.5)))
=>
(assert (AgudezaVisual (estado APTO)))
)
(defrule R2
(AgudezaVisual (agudezaVisual ?a & : (< ?a 0.5)))
=>
(assert (AgudezaVisual (estado NO_APTO)))
)
(defrule R3
(Bucodental (hayDientesDañados true))
(Bucodental (hayCaries true))
(Bucodental (hayDientesConConcavidades true))
(Bucodental (haySangradoOInflamacionLengua true))
(Bucodental (haySangradoOInflamacionPaladar true))
=>
(assert (Bucodental (estado NO_APTO)))
)
(defrule R4
(Bucodental (presentaCancerOral true))
=>
(assert (Bucodental (estado NO_APTO)))
)
(defrule R5
(Bucodental (tieneGengivitis true))
=>
(assert (Bucodental (estado APTO)))
)
(defrule R6
(Respiratorio (tieneDisnea true))
(Respiratorio (tieneJadeo true))
=>
(assert (Respiratorio (estado NO_APTO)))
)
(defrule R7
(or (Respiratorio (tieneTos true))
(Respiratorio (tieneJadeo true)))
=>
(assert (Respiratorio (estado NO_APTO)))
)
(defrule R8
(Respiratorio (tieneTos true))
(Respiratorio (tieneEsputo true))
(Respiratorio (tieneDolorToracico true))
=>
(assert (Respiratorio (estado NO_APTO)))
)
(defrule R9
(Respiratorio (tieneDisnea true))
(Respiratorio (tieneEdema true))
=>
(assert (Respiratorio (estado NO_APTO)))
)
(defrule R10
(Respiratorio (tieneDolorToracico true))
=>
(assert (Respiratorio (estado APTO)))
)
(defrule R11
(Digestivo (tieneCirrosis true))
=>
(assert (Digestivo (estado NO_APTO)))
)
(defrule R12
(Digestivo (esCeliaco true))
=>
(assert (Digestivo (estado APTO)))
)
(defrule R13
(Digestivo (esDiabetico true))
=>
(assert (Digestivo (estado APTO)))
)
(defrule R14
(Digestivo (tieneHepatitisB true))
(Digestivo (tieneHepatitisC true))
=>
(assert (Digestivo (estado NO_APTO)))
)
(defrule R15
(Digestivo (tieneHepatitisB true))
(Digestivo (esCeliaco true))
=>
(assert (Digestivo (estado NO_APTO)))
)
(defrule R16
(Electrocardiograma {frecuenciaCardiaca < 60})
=>
(assert (Electrocardiograma (estado NO_APTO)))
)
(defrule R17
(Electrocardiograma {frecuenciaCardiaca < 100})
(Electrocardiograma {frecuenciaCardiaca > 59})
=>
(assert (Electrocardiograma (estado APTO)))
)
(defrule R18
(Electrocardiograma {frecuenciaCardiaca > 100})
(Electrocardiograma (tieneArritmia true))
=>
(assert (Electrocardiograma (estado NO_APTO)))
)
(defrule R19
(Electrocardiograma {frecuenciaCardiaca < 60})
(Electrocardiograma (tieneInsuficienciaCardiaca true))
=>
(assert (Electrocardiograma (estado NO_APTO)))
)
(defrule R20
(Electrocardiograma (tieneMiocarditis true))
(Electrocardiograma (tienePericarditis true))
=>
(assert (Electrocardiograma (estado NO_APTO)))
)
However, when I run the inference engine i get the next error:
Exception in thread "main" Jess reported an error in routine <
while executing (< ?__synth0(0,0,-1) 60)
while executing rule LHS (TEQ)
while executing rule LHS (TECT)
while executing (assert (MAIN::Electrocardiograma (frecuenciaCardiaca nil) (tieneInsuficienciaCardiaca nil) (tieneArritmia nil) (tienePericarditis nil) (tieneMiocarditis nil) (estado APTO)))
while executing defrule MAIN::R17.
Message: compareTo threw an exception.
at jess.AbstractComparison.call(AbstractComparison.java:30)
at jess.FunctionHolder.call(FunctionHolder.java:35)
at jess.Funcall.execute(Funcall.java:338)
at jess.FuncallValue.resolveValue(FuncallValue.java:29)
at jess.Node1TEQ.callNodeRight(Node1TEQ.java:33)
at jess.Node1.passAlong(Node1.java:49)
at jess.Node1TECT.callNodeRight(Node1TECT.java:40)
at jess.NodeRoot.passAlong(NodeRoot.java:39)
at jess.NodeRoot.callNodeRight(NodeRoot.java:14)
at jess.FactList.processToken(FactList.java:31)
at jess.FactList._assert(FactList.java:210)
at jess.FactList.assertFact(FactList.java:181)
at jess.Rete.assertFact(Rete.java:548)
at jess.FactFunctions$Assert.call(FactFunctions.java:50)
at jess.FunctionHolder.call(FunctionHolder.java:35)
at jess.Funcall.execute(Funcall.java:338)
at jess.Defrule.fire(Defrule.java:407)
at jess.Activation.fire(Activation.java:98)
at jess.Agenda.run(Agenda.java:267)
at jess.Agenda.run(Agenda.java:243)
at jess.Rete.run(Rete.java:1829)
at jess.Rete.run(Rete.java:1824)
at Main.main(Main.java:96)
Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at java.lang.String.compareTo(String.java:111)
at jess.Lt.computeComparable(ArithmeticFunctions.java:165)
at jess.AbstractComparison.call(AbstractComparison.java:27)
... 22 more
I 've grateful if you could helpme.
On the right hand side of rule R17 you assert
Electrocardiograma (estado APTO)
but during this assert all the constraints for Electrocardiograma in all the rules are evaluated. This includes rule R16 wheren this Electrocardiograma's frecuenciaCardiaca is compared to 60. But this slot has not been set, so it remains at nil. Therefore the comparison using <, the numeric comparison operator, is bound to fail.
(Note: Don't use 59 and 60. It is much clearer to use <60 and >=60.)
If you really want to assert another (!) Electrocardiograma fact you should provide at least safe values for all slots. (It is more likely that you want to modify the Electrocardiograma fact to hold the outcome of )

JessTab: Can we count all subclass instances?

I have a class A which consists of two subclasses B and C. Class B has three instances, while C two. Can I write a JessTab rule which will count all implicit instances of A i.e. give me 5?
Mapping class A in Jess:
(mapclass http...#A)
Rule to count instances which gives me 0 since there are no direct instances of A:
Originally:
(defrule countAinstances
?c <- (accumulate (bind ?count 0)
(bind ?count (+ ?count 1))
?count
(object (ís-a http...#A))
)
=>
(printout t ?c " number of class A instances." crlf))
This doesn't count instances of subclasses of A.
Modified version:
(defrule countAinstances
?c <- (accumulate (bind ?count 0)
(bind ?count (+ ?count 1))
?count
(object (OBJECT ?x&:(instanceof ?x http...#A)))
)
=>
(printout t ?c " number of class A instances." crlf))
The following error appears:
Jess reported an error in routine instanceof while executing
(instanceof ?_20_x(0,2,-1) http...#A) while executing rule LHS (TEQ)
while executing rule LHS (TECT). Message: Class not found:
http...#A. Program text: ( defrule countAinstances ?c <- (
accumulate ( bind ?count 0 ) ( bind ?count ( + ?count 1 ) ) ?count (
object ( OBJECT ?x & : ( instanceof ?x http...#A ) ) ) ) = > (
printout t ?c " number of class A instances." crlf ) ) at line 20.
Nested exception is: http...#A
Access the object and rely on Jess' own function instanceof, not the protege slot is-a:
(object (OBJECT ?x&:(instanceof ?x A)))
Use the full class name if A isn't imported.
if you don't have the Java class name, you'll have to test for all classes and subclasses in that pattern, using an (or) function. Rather tedious.
Later
Seeing that is-a contains class references that can be compared to class names, this would be the simplest way of writing the rule:
defrule countAinstances
?c <- (accumulate (bind ?count 0)
(bind ?count (+ ?count 1))
?count
(object (is-a ?x&B|C))
)
=>
(printout t ?c " number of subclass instances." crlf))
The complete solution-rule is as follows:
(defrule countAinstances
?c <- (accumulate (bind ?count 0)
(bind ?count (+ ?count 1))
?count
(object (is-a ?x&:(or (= ?x B)(= ?x C))))
)
=>
(printout t ?c " number of subclass instances." crlf))

CLIPS constant compiler directive

Similar to the compiler directive for constants in C, is there a way I can do the following in CLIPS?
#define INFINITY 1000000000
(deftemplate foo
(slot num (type INTEGER) (default INFINITY))
)
...
(defrule bar
(foo (num INFINITY))
=>
...
)
You can define a global variable and treat it as a constant:
CLIPS> (defglobal ?*INFINITY* = 1000000000)
CLIPS>
(deftemplate foo
(slot num (type INTEGER) (default ?*INFINITY*)))
CLIPS>
(defrule bar
(foo (num ?num&:(eq ?num ?*INFINITY*)))
=>)
CLIPS> (assert (foo))
<Fact-1>
CLIPS> (facts)
f-0 (initial-fact)
f-1 (foo (num 1000000000))
For a total of 2 facts.
CLIPS> (agenda)
0 bar: f-1
For a total of 1 activation.
CLIPS>

Clips matching expression is not working

hello in clips i have this template:
(deftemplate cell(slot x)(slot y)(slot alive))
and this fact :
(start 1 1)
then i have this claus in the LHS :
?start<-(start ?x ?y)
and i want to get the variable ?a1
(cell (x (+ ?x 1) )(y ?y)(alive ?a1))
it seems that it's not allowed to add to the variable "(+ ?x 1)" so how
can i achieve what i want.
CLIPS> (deftemplate cell (slot x) (slot y) (slot alive))
CLIPS>
(deffacts initial
(start 1 1)
(cell (x 2) (y 1) (alive yes)))
CLIPS>
(defrule example
(start ?x ?y)
(cell (x =(+ ?x 1)) (y ?y) (alive ?a1))
=>
(printout t "?a1 = " ?a1 crlf))
CLIPS> (reset)
CLIPS> (run)
?a1 = yes
CLIPS>

Resources