JessTab in Protege - jess

I'm using Jess with Protege, I created a def template Person with the slots (name, age and adress), and I created another def template which extends the first one with the additional slot (sex), now I want to delete the first one and replace it by the new one, and I don't want to lose instances, I want the instances of the first one to be extended by the second, how can I do it ?
thank you
i tried first to modify the structure of the def template with the function "replace$", but it doesn't work, then I tried the function "modify" but it just modifies the value of a slot
(deftemplate Person (slot name(type string)) (slot age(type integer)) (slot adress(type string)))
(deftemplate Personne (slot name(type string)) (slot age(type integer)) (slot adress(type string)) (slot sexe (type string) ))
(assert( Person (name "Bryan") (age "25") (adress "New York")))
(assert( Person (name "Omar") (age "35") (adress "Algeria")))
(assert( Person (name "Sara") (age "30") (adress "Moroco")))
When I tried to use the function "replace$" into a rule, I had no syntaxique error, the syntax is correct, but when I do (run) it does not work, no rule is executed.

There’s no way to change the instances themselves during a single run of the program. But you could save them to a file, edit the file, and load them back in.

Related

is it possible to use the result of a defquery by a defrule?

i'm moving along in jess. the problem that i'm using jess for is to allocate docks
to members based on a set of rules. the process starts when a dock is put in the
pool of available docks. the list of available docks is then compared to the
dock request list. i did this part using a defquery. for simplicity i have just
one available dock with 2 members requesting it. at this point i would like to
start to apply the rules to the result of the query.
i have successfully tested the defquery and the defrule - separately, but don't
understand how to have the rule act on the defquery result.
is it possible?
i have included the defrule and defquery below
duetto
(defglobal ?*curSlip* = nil ?*cand* = nil)
(deftemplate bid
(slot person)
(slot slipRequestedID)
(slot boatID))
(deftemplate slip
(slot slipID)
(slot slength)
(slot swidth)
(slot sdepth))
(deftemplate person
(slot name)
(slot bycseniority)
(slot boatID)
(slot currentSlip))
(deffacts members
(person (name John)(bycseniority 34)(boatID GEM)(currentSlip A8))
(person (name Joe)(bycseniority 50)(boatID MS#$)(currentSlip B9))
(person (name Frank)(bycseniority 120)(boatID DoryO)(currentSlip B8)))
(deffacts bids
(bid (person John) (slipRequestedID A13) (boatID GEM))
(bid (person Joe) (slipRequestedID A13) (boatID FarNiente))
(bid (person Frank) (slipRequestedID B9) (boatID DoryO)))
(deffacts freeSlips
(slip (slipID A13)))
(defrule mostSenior
(person (name ?name) (bycseniority ?senior))
(not (person (name ~?name) (bycseniority ?bycmem&:(< ?bycmem ?senior))))
=>
(bind ?*cand* ?name)
(printout t ?*cand* " is the most senior." crlf))
(defquery bidLookup
(declare (variables ?slipID))
(bid (person ?pers) (slipRequestedID ?slipID)))
(reset)
(bind ?collOfBids (run-query* bidLookup A13))
(while (?collOfBids next)
(printout t (?collOfBids getString pers) crlf)
)
You are leaving the rule-based approach after locating the most senior person. The fact(s) you need for assigning (or denying) a slot request to the most senior person are already in working-memory. Therefore, running a query doesn't yield any new information.
You could add conditions to the mostSenior rule, first establishing that the most senior person has made a bid (any bids) and, second, that the requested slip has a matching slip. If this rule fires, you have the first allocation (and may remove a bid and a slip).
You'll need to consider what happens when the most senior member isn't requesting anything: perhaps write another rule to remove him from WM. Also, a bid of the most senior member may not have a match, and you may have to remove that to make the "senior-has-no-bids" rule to fire.
Don't worry about duplicating conditions in different rules. The engine is built to deal efficiently with this.

Compare value of a nested java bean

I am trying my hands with JESS wherein I want to write a rule as following.
When order amount is greater than 1000 and customer is preferred and customer name matches to order name then do something.
My Order.java has following properties
int amount, Customer cust
And Customer.java is a plain bean class holding following properties.
string name, string address
I am not able to find a way wherein I can get the value of Order.cust.name and compare with Customer.name in JESS.
Can anyone help me here please?
I tried using following but not working out for me.
(defrule HelloCustomer "When customer is preferred and amount is greater than 1001"
?person1 <- (Customer)
?cust <- (Customer {isPreferred == true})
?o <- (Order{amount > (+ 1000 1)})
?person2 <- (Order(customerA))
?person2Name <- (Customer{name == (Order{customerA.name})})
=>
(modify ?o (totalAmount 1000))
(printout t "Found two different " (call ?person2.customerA getName) crlf))
(printout t "Found two different*** " ?person1.name crlf))
You have many of the details right but the fundamentals are mostly wrong. First, note that each “Customer” and “Order” pattern matches a new object; this might match as many as five different objects. Secondly, you’ll need to bind variables to slot values so you can test them in other slots. Lastly, you’ll need to make use of the “OBJECT” slot to retrieve the Java object represented by each of this patterns. Roughly, I think you want something like
(defrule HelloCustomer
(Customer {isPreferred == true} (name ?name) (OBJECT ?customer))
(Order {amount > 1001} (name ?name) (OBJECT ?order)) ;; Repeating variable binds these together
=>
;; do something with ?customer and ?order
The Jess manual covers all of this, but you do have to read the whole thing. After all, you’re learning a whole new programming language.

In Ada, How do I recursively map and memory manage a type within itself

I've been struggling with this little issue for a while. I am trying to create my own implementation of an internal JSON structure. The challenge is that with Ada I have to use an access type to make it recursive and access types have the risk of leaking if I don't have it tightly controlled. In order to make it controlled, I kept all the real activity private I provided Get (Source:...) and Set (Target:...; Value:...) functions/procedures for the Node type that will attempt to verify and handle any existing Vector (json-array) or Map (json-object) elements. In order to further ensure that I was using stable features of Ada 2012 and catching contents as they go out of scope, I tried to use a Protected_Controlled type and "managing" Ada libraries, but found that the container libraries couldn't handle protected types, so I used simply Controlled. The Finalize (...) procedure is for any Vector or Map types and recursively frees the Node_Value.Reference.
My question is if I am applying Ada 2012 correctly, or else how do I create a memory managed recursion of a type that could be either a vector/map or a string/number?
private
...
type Node_Access is access Node;
type Node_Value is new Ada.Finalization.Controlled with record
Reference : Node_Access;
end record;
overriding procedure Initialize (Item : in out Node_Value);
overriding procedure Adjust (Item : in out Node_Value);
overriding procedure Finalize (Item : in out Node_Value);
...
package Of_Array is new Ada.Containers.Indefinite_Vectors (Natural, Node_Value);
package Of_Object is new Ada.Containers.Indefinite_Ordered_Maps (Wide_String, Node_Value);
type Node is record
...
Vector : aliased Of_Array.Vector;
Object : aliased Of_Object.Map;
end record
with Size => 96;
procedure Free is new Ada.Unchecked_Deallocation (Node, Node_Access);
The way to do it (in my opinion) is to use OOP and have an abstract element as the root node of a family of types representing the different kinds of data which can be stored.
An array of elements can then be implemented as a vector of the class rooted at the abstract element type. An "object" can be implemented as a hash-table with a string key and the class rooted at the abstract element type as the values.
Self-referential types without access types are a valid use for type extension in combination with an indefinite container. A simple example is S-expressions, or Sexes. A Sex is either an atom or a list of zero or more Sexes. The right way to be able to do this would be
with Ada.Containers.Indefinite_Vectors;
package Sexes is
type Sex is private;
-- Operations on Sex
private -- Sexes
package Sex_List is new Ada.Containers.Indefinite_Vectors
(Index_Type => Positive, Element_Type => Sex); -- Illegal
type Sex (Is_Atom : Boolean := False) is record
case Is_Atom is
when False =>
Value : Atom;
when True =>
List : Sex_List.Vector;
end case;
end record;
end Sexes;
but Ada doesn't allow this. We can use type extension to get around this:
private -- Sexes
type Root is tagged null record;
package Sex_List is new Ada.Containers.Indefinite_Vectors
(Index_Type => Positive, Element_Type => Root'Class);
type Sex (Is_Atom : Boolean := False) is new Root with record
case Is_Atom is
when False =>
Value : Atom;
when True =>
List : Sex_List.Vector;
end case;
end record;
end Sexes;
which is legal. The only catch is that you have to convert anything taken from List to Sex (or Node in your case).
HTH; sorry about the late response.

How to have an argument possible values dependent on another argument with IPython Widgets?

Assume I have this simple function in Python:
def f(gender, name):
if gender == 'male':
return ranking_male(name)
else:
return ranking_female(name)
where gender belongs to ['male', 'female'] whereas name belongs to ['Adam', 'John', 'Max', 'Frodo'] (if gender is male) or ['Mary', 'Sarah', 'Arwen'] (otherwise).
I wish to apply interact from ipywidgets to this function f. Normally one would do
from ipywidgets import interact
interact(f, gender = ('male', 'female'), name = ('Adam', 'John', 'Max', 'Frodo'))
The problem is that the admissible values for name now depend on the value chosen for gender.
I tried to find it in the docs but couldn't find it. The only thing I think may be important is
This is used to setup dynamic notifications of trait changes.
Parameters
----------
handler : callable
A callable that is called when a trait changes. Its
signature should be ``handler(change)``, where ``change```is a
dictionary. The change dictionary at least holds a 'type' key.
* ``type``: the type of notification.
Other keys may be passed depending on the value of 'type'. In the
case where type is 'change', we also have the following keys:
* ``owner`` : the HasTraits instance
* ``old`` : the old value of the modified trait attribute
* ``new`` : the new value of the modified trait attribute
* ``name`` : the name of the modified trait attribute.
names : list, str, All
If names is All, the handler will apply to all traits. If a list
of str, handler will apply to all names in the list. If a
str, the handler will apply just to that name.
type : str, All (default: 'change')
The type of notification to filter by. If equal to All, then all
notifications are passed to the observe handler.
But I have no idea how to do it nor to interpret what the doc string is talking about. Any help is much appreciated!
For example you have brand and model of car and model depends on brand.
d = {'Volkswagen' : ['Tiguan', 'Passat', 'Polo', 'Touareg', 'Jetta'], 'Chevrolet' : ['TAHOE', 'CAMARO'] }
brand_widget = Dropdown( options=list(d.keys()),
value='Volkswagen',
description='Brand:',
style=style
)
model_widget = Dropdown( options=d['Volkswagen'],
value=None,
description='Model:',
style=style
)
def on_update_brand_widget(*args):
model_widget.options = d[brand_widget.value]
brand_widget.observe(on_update_brand_widget, 'value')
I've used nested widgets to solve this problem. It'll work, but it's ugly, partially because it doesn't seem to be a common use case in ipywidgets (see discussion).
Given your function f(gender, name) you can define an intermediate wrapper:
def f_intermediate_wrapper(gender):
if gender=="male":
possible_names = ['Adam', 'John', 'Max', 'Frodo']
else:
possible_names = ['Mary', 'Sarah', 'Arwen']
try:
f_intermediate_wrapper.name_widget.widget.close()
except AttributeError:
pass
f_intermediate_wrapper.name_widget = interact(f,
gender=widgets.fixed(gender),
name = possible_names)
The first part sets the possible name options given the gender, as desired.
The second part closes the name_widget from your previous evaluation, if it exists. Otherwise, every time you change the gender, it'll leave up the old list of names, which are the wrong gender (see example).
The third part creates a name widget of the possible names for that gender, and stores it somewhere sufficiently static. (Otherwise, when you change the gender the old name widget will be out of scope, and you won't be able to close it.)
Now you can create your gender and name widget:
gender_and_name_widget = interact(f_intermediate_wrapper,
gender = ["male", "female"])
And you can access the result of your f(gender, name) using
gender_and_name_widget.name_widget.widget.result

How to compare java object in jess

I have a problem when I compare java object as attribute inside the java class
This is my clp file
(import Model.*)
(deftemplate PizzaBase
(declare (from-class PizzaBase)
(include-variables TRUE)))
(deftemplate PizzaTopping
(declare (from-class PizzaTopping)
(include-variables TRUE)))
(deftemplate Pizza
(declare (from-class Pizza)
(include-variables TRUE)))
(defrule make-pizza
?pizzaBase1 <-(PizzaBase{size == 9})
(Pizza(pizzaBase ?pizzaBase1))
=>
(add (new PizzaBase "New DeepPan" 10))
)
According from my rule, I want to create a new pizzaBase.When the pizzaBase object in Pizza equal pizzaBase1(size = 9), but JESS is not create a new fact for me.
From my thinking, I think JESS cannot compare the Java object that create from the class.Therefore, There isn't add any fact to JESS.
So,"How to solve this problem?",because I look on the manual on the JESS website but there aren't any title that according my problem.
Thank!
You may have overlooked section 5.3.2., Adding Java objects to working memory.
A Java object isn't the same as a fact, even when you derive a shadow (!) fact from a POJO, using from-class and include-variables. A fact contains a reference to the Java object you insert by calling (add ?aNewObject) in the reserved slot name OBJECT.
Change your rule like this:
(defrule make-pizza
(PizzaBase{size == 9}(OBJECT ?pizzaBase1))
(Pizza(pizzaBase ?pizzaBase1))
=>
(add (new PizzaBase "New DeepPan" 10))
)