0

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

laune
  • 31,114
  • 3
  • 29
  • 42
Edi
  • 109
  • 11

2 Answers2

1

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))
laune
  • 31,114
  • 3
  • 29
  • 42
  • I modified the question to include your proposed alternative – Edi Jan 03 '15 at 11:21
  • @Edi Don't you have class names as they are used in Java? This "http...#A" stuff can't be a class name - wrong syntax. – laune Jan 03 '15 at 11:48
  • I have used that for brevity. It's full URL is: [https://wiki.csc.calpoly.edu/OntologyTutorial/family_example.owl#A] @laune – Edi Jan 03 '15 at 12:05
  • That's not a Java class name either. - See my extension to the answer. – laune Jan 03 '15 at 12:06
  • @Edi, don't remove the original question text - otherwise answer and comment exchange become unintellegible. You can add to a question - see my edit of your Q – laune Jan 03 '15 at 12:09
  • Ok I thought it had to be changed – Edi Jan 03 '15 at 12:18
  • One cannot use OR within accumulate condition based on our past experience – Edi Jan 03 '15 at 12:19
  • 1
    You can use an or function in a slot constraint: `?x&:(or (instanceof ?x A) (instanceof ?x B))` – laune Jan 03 '15 at 12:29
  • With Java classes the same error appears: Class not found. I tried with is-a slot and got the result. – Edi Jan 03 '15 at 13:09
  • I woould like to do the calculation automatically i.e. loop in each subclass and count the instances. There is a JessTab command class-subclasses which returns all class subclasses, but cannot loop within it with foreach construct. Any suggestion? – Edi Jan 03 '15 at 13:14
  • Normally I'd insert a fact containing the (Java) class and accumulate facts where the object is an instanceof the class (or the is-a slot contains that class). This would give me the fact counts per class. – laune Jan 03 '15 at 14:20
0

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))
Edi
  • 109
  • 11