Clips matching expression is not working - expert-system

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>

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>

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>

Can xmonad make our often used functions available anytime?

We have some functions needed to be called at any time and places. For example:
(defun winG (qty pb ps)
(- (* qty ps (- 1 SXF YHS)) (* 2 GHF) (* qty pb (+ 1 SXF))))
(defun winQ (qty pb ps)
(- (* qty ps (- 1 SXF)) (* 2 GHF) (* qty pb (+ 1 SXF))))
(defun stopLoss (qty pb &optional (lossRate 0.02))
(let ((tot (* qty pb (+ 1 SXF))))
(format t "Stop Loss at:~$~%" (- pb (/ (* tot lossRate) qty)))
(format t "Lost Money:~$(~d%)~%" (* tot lossRate) (* 100 lossRate))))
(defun div618 (p1 p2)
(let ((ratio '(0. 0.191 0.236 0.382 0.5 0.618 0.809 1.))
(price #'(lambda (r) (if (<= p1 p2) (+ p1 (* (- p2 p1) r)) (- p1 (* (- p1 p2) r))))))
(if (<= p1 p2)
(dolist (r (reverse ratio)) (format t "-------~3$ ~$-------~%" r (funcall price r)))
(dolist (r ratio) (format t "-------~3$ ~$-------~%" r (funcall price r))))))
Now we use stumpwm which can load our functions once started and we can call those functions just by striking hot key to open its eval window at any time and places. It is VERY convenient. However, the stumpwm is not VERY steady as xmonad. So we want to use xmonad instead of stumpwm and we donot mind to implement those Common Lisp functions using haskell.
Any suggestion is appreciated!
you should be able to do this via something like this
myKeys conf#(XConfig {XMonad.modMask = modm}) = M.fromList $
[ ((modm, xK_F1 ), spawn $ XMonad.terminal conf) --starts the terminal
, ((mod4Mask,xK_F1 ), spawn "gvim" >> -- you can concatenate commands too
spawn "notify-send -t 1000 gVim" >>
focusUrgent) -- or haskell functions
, ((mod4Mask,xK_F2 ), spawn "lisp evaluate lispy function")
, ((modm, xK_F3 ), haskellFunctionPortedFromLisp )]
hope this helps.

Access a slot from multifield in deffunction

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>

Resources