find relation in CLIPS expert systems - expert-system

How can I find the relation between two or more family members in a family tree using CLIPS. I tried this rule but it's not working. I have a syntax Error.
Is there any hints to avoid the Error.
(defrule Family
(FamilyTree ?L-name ?F-name)
=>
(assert(FamilyTree ?L-name ?F-name(read))
(printout t ?L-name "is parent of" ?F-name crlf)))

There appears to be some critical information missing from your question. The code snippet you posted loads correctly. It's only when I add a FamilyTree deftemplate that I get the error you described. If you use deftemplate facts in your rules, you have to use the syntax for deftemplate facts which requires specifying the slot name.
CLIPS> (clear)
CLIPS>
(defrule Family
(FamilyTree ?L-name ?F-name)
=>
(assert(FamilyTree ?L-name ?F-name(read))
(printout t ?L-name "is parent of" ?F-name crlf)))
CLIPS> (clear)
CLIPS> (deftemplate FamilyTree (slot last-name) (slot first-name))
CLIPS>
(defrule Family
(FamilyTree ?L-name ?F-name)
=>
(assert(FamilyTree ?L-name ?F-name(read))
(printout t ?L-name "is parent of" ?F-name crlf)))
[PRNTUTIL2] Syntax Error: Check appropriate syntax for deftemplate patterns.
ERROR:
(defrule MAIN::Family
(FamilyTree ?L-name
CLIPS>

Related

Revit API - How to Access Family Parameters "Discipline" and "Type of Parameter"

i am trying to filter my list of a family parameters by their Discipline.
But i do not know how to access it. The same goes for the "Type of Parameter" as you see in the image.
List<FamilyParameter> famParm_lst = FamMngr.GetParameters().Cast<FamilyParameter>().ToList();
List<FamilyParameter> famParm_PipeSize_lst = famParm_lst.Where(fp => fp.Definition.(Discipline) == (Pipe Size)).Select();
Any idea on how i can check for a Discipline of a value "Pipe Size" ?
Look at FamilyParameter Class → Definition Property
→ Definition Members.
So this is how I got the Discipline and the "Type of Parameter":
//tmpParam is a Family Parameter
string getDateTypeId = tmpParam.Definition.GetDataType().TypeId;
string Discipline = getDateTypeId.Split(':')[0].Split('.').Last();
string TypeOfParameter = getDateTypeId.Split(':')[1].Split('-')[0];

Using slot-insert$ in Jess Tab /Protege

The following code in the Jess Tab continuously inserts the same instance into a multivalued slot.
(defrule satisfactibleEstudio
(object (is-a Estudio)
(OBJECT ?user)
(nombre ?name)
(preferencias_minimas ?pref))
(object (is-a Chalet)
(OBJECT ?viv)
(precio ?p&: (and
(>= ?p (slot-get ?pref precio_minimo))
(<= ?p (slot-get ?pref precio_maximo))))
(tamanno ?t&: (and
(>= ?t (slot-get ?pref tamanno_minimo))
(<= ?t (slot-get ?pref tamanno_maximo))))
(componentes $?comp&: (>= (get-dorms $?comp) (slot-get ?pref dormitorios))))
=>
(slot-insert$ ?user satisfactibles 1 ?viv))
However, if I replace the slot-insert$ function by a printout it works as intended. What am I doing wrong?
Update:
So apparently it's continuously inserting the same instance into the slot, however with a printout it only prints once per match.
See the Jess manual about modifying a fact on the right hand side:
If a rule includes the declaration (declare (no-loop TRUE)), then nothing that a rule does while firing can cause the immediate reactivation of the same rule; i.e., if a no-loop rule matches a fact, and the rule modifies that same fact such that the fact still matches, the rule will not be put back on the agenda, avoiding an infinite loop.

How do I do nested foralls in Drools?

Question
Considering these classes:
class BookCase { ArrayList<Book> books }
class Book { ArrayList<Page> pages }
class Page { String color }
And considering this natural language rule:
When all pages in a bookcase are black, do A
The trivial approach would be to nest forall clauses, but in Drools can't do that, because forall clauses only allow Patterns (not Conditional Elements, what a forall clause is) inside!
How do I express this in Drools then?
This is close, but not quite the right thing:
rule "all black pages"
when
BookCase( $books: books )
$book: Book( $pages: pages ) from $books
not Page( color != "black" ) from $pages
then
System.out.println( "doing A" );
end
The problem is that this will fire once for each book where all pages are black. To assess all pages in all books one could assemble a list of all pages and make sure they are all black:
rule "all black pages, take 2"
when
BookCase( $books: books )
$pages: ArrayList() from accumulate( Book( $ps: pages ) from $books,
init( ArrayList list = new ArrayList(); ),
action( list.addAll( $ps ); ),
result( list ) )
not Page( color != "black" ) from $pages
then
System.out.println( "doing A" );
end
You can actually nest multiple foralls if you don't use forall(p1 p2 p3...), but the equivalent not(p1 and not(and p2 p3...)). Then, to keep individual books and pages from firing the rule, chuck an exists in between there.
rule 'all pages in bookcase are black'
when
(and
$bookCase: BookCase()
(not (exists (and
$book: Book() from $bookCase.books
not( (and
not( (exists (and
$page: Page() from $book.pages
not( (and
// slightly different constraint than I used in question
eval($page.color == $book.color)
) )
) ) )
) )
) ) )
)
then
...
end
Unlike using accumulate to create a flat list of all pages, this will maintain the context of $page, that is, when a page is put in a constraint with its parent book as in the example above, in this solution Drools still 'knows' what the parent book is.
While I was writing the question, I think I found the answer myself:
BookCase($caseContents : books)
$bookWithOnlyBlackPages : ArrayList<Page>() from $caseContents
forall ( $page : Page(this memberOf $bookWithOnlyBlackPages)
Page(this == $page,
color == "black") )
forall ( $bookInCase : ArrayList<Page>(this memberOf $caseContents)
ArrayList<Page>(this == $bookInCase,
this == $bookWithOnlyBlackPages) )

Jess rule definition [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I use the Jess Rule Engine in Protégé.
I need to create a test rule using classes, I defined in Jess code.
Here are classes & instances definition code:
(clear)
(defclass Student
(is-a :THING)
(slot studId (type string))
(slot studName (type string))
(slot satGrade (type integer))
)
(defclass Course
(is-a :THING)
(slot courseId (type string))
(slot courseName (type string))
(slot passGrade (type integer))
)
(defclass StudentInCourse
(is-a :THING)
(slot studId (type string))
(slot courseId (type string))
(slot finalGrade (type integer))
)
(make-instance stud_01 of Student (studId "s123") (studName "Rob") (satGrade 650))
(make-instance stud_02 of Student (studId "s456") (studName "Pete") (satGrade 700))
(make-instance stud_03 of Student (studId "s789") (studName "Alex") (satGrade 770))
(mapclass Student)
(deffacts Student (Student (studId)(studName)(satGrade)))
(make-instance course_01 of Course (courseId "c123") (courseName "Calculus") (passGrade 60))
(make-instance course_02 of Course (courseId "c456") (courseName "Linear Algebra") (passGrade 70))
(mapclass Course)
(deffacts Course (Course (courseId)(courseName)(passGrade)))
(make-instance studInCourse_01 of StudentInCourse (studId "s123") (courseId "c123") (finalGrade 20))
(make-instance studInCourse_02 of StudentInCourse (studId "s123") (courseId "c456") (finalGrade 90))
(make-instance studInCourse_03 of StudentInCourse (studId "s456") (courseId "c123") (finalGrade 80))
(make-instance studInCourse_04 of StudentInCourse (studId "s789") (courseId "c456") (finalGrade 75))
(mapclass StudentInCourse)
(deffacts StudentInCourse (StudentInCourse (studId)(courseId)(finalGrade)))
Now I want to implement a check who among the students passes the course «Linear Algebra», I know how to implement it in SQL/Java/C#, but I can't understand how exactly to write it in Jess, each string I push to Jess returns a parsing/compilation error.
How exactly to implement kind of join in Jess or pass over the collection, get courseID, to compare the values according to ID and passGrade/finalGrade, for the correct values to retrieve the data from the student class and as the result to return something like: «Pete passed course Linear Algebra with grade 80»?
It's been ages since I touched Protege, but based on what you have above, I'm assuming you have facts like these (among others). The "deffacts" you have above must be notional at this point -- they won't do anything good (and may not even parse).
(Student (studId "s123")(studName "Rob")(satGrade 650))
(StudentInCourse (studId "s123") (courseId "c456") (finalGrade 90))
(Course (courseId "c456") (courseName "Linear Algebra") (passGrade 70))
Given that I'm right about the above, then a rule that reported each student who passed any course might look like
(defrule passed-algebra
(Course (courseName ?cn) (courseId ?cid) (passGrade ?pg))
(StudentInCourse (courseId ?cid) (studId ?sid) (finalGrade ?fg&:(>= ?fg ?pg))
(Student (studName ?name) (studId ?sid))
=>
(printout t ?name " passed course " ?cn " with a grade of " ?fg crlf))

error running JSON2XML_ST

i try to run JSON2XML_ST ike this:
bab#maz:~/tpantlr2-code/code/listeners$ antlr4 JSON.g4
bab#maz:~/tpantlr2-code/code/listeners$ javac JSON2XML_ST.java
bab#maz:~/tpantlr2-code/code/listeners$ java JSON2XML_ST t.json
but a i got :
(json (object { (pair "description" : (value "An imaginary server config file")) ,
(pair "logs" : (value (object { (pair "level" : (value "verbose")) , (pair "dir" :
(value "/var/log")) }))) , (pair "host" : (value "antlr.org")) , (pair "admin" : (value
(array [ (value "parrt") , (value "tombu") ]))) , (pair "aliases" : (value (array [
]))) }))
Exception in thread "main" java.lang.IllegalArgumentException: No such group file: XML.stg
at org.stringtemplate.v4.STGroupFile.<init>(STGroupFile.java:69)
at org.stringtemplate.v4.STGroupFile.<init>(STGroupFile.java:48)
at JSON2XML_ST$XMLEmitter.<init>(JSON2XML_ST.java:45)
at JSON2XML_ST.main(JSON2XML_ST.java:140)
why ?? can anybody help me? thank you.
This is an XML.stg that can be used with JSON2XML_ST.java. The source download still doesn't contain XML.stg. It is however a good learning exercise to come up with this file yourself. It was for me.
group XML;
empty() ::= ""
value(x) ::= "<x>"
object(fields) ::= <<
<fields; separator="\n">
>>
enclose_element(x) ::= <<
\<element><x>\</element>
>>
array(values) ::= <<
<values:enclose_element(); separator="\n">
>>
tag(name,content) ::= <<
\<<name>\><content>\</<name>\>
>>
The problem is that XML.stg is not part of the source. i.e. when you run the example the file XML.stg does not exist and therefore cannot be found, hence the error of No such group file.
Exception in thread "main" java.lang.IllegalArgumentException: No such group file: XML.stg
This seems to be a known problem and has been reported in the ANTLR errata:
http://pragprog.com/titles/tpantlr2/errata
50831:
There is a reference to JSON2XML_ST.java source which uses StringTemplate for XML translation. But in the source code itself there is reference to the XML.stg file which absent in the book source archive.
JSON2XML_ST.java (line 45):
STGroup templates = new STGroupFile("XML.stg");
It would be nice if you put it to archive, since (IMHO) it's not very easy to find it elsewhere.
Thanks.
There is a reference to xml.stg here: http://www.antlr.org/wiki/plugins/viewsource/viewpagesrc.action?pageId=16220704 which you could use.
Create a new file and call it XML.stg and put in the following contents:
group XML;
file(props) ::= <<
\<properties>
<props; separator="\n">
\</properties>
>>
prop(ID,v) ::= "\<property id=\"<ID>\"><v>\</property>"
Then rerun the example as you already have and it might work.

Resources