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))
)
Related
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.
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.
data Task = Task
{ id :: String
, description :: String
, dependsOn :: [String]
, dependentTasks :: [String]
} deriving (Eq, Show, Generic, ToJSON, FromJSON)
type Storage = Map String Task
s :: Storage
s = empty
addTask :: Task -> Storage -> Storage
addTask (Task id desc dep dept) = insert id (Task id desc dep dept)
removeTask :: String -> Storage -> Storage
removeTask tid = delete tid
changes = [addTask (Task "1" "Description" [] []), removeTask "1"]
main = putStrLn . show $ foldl (\s c -> c s) s changes
Suppose I have the following code. I want to store changes list in a json file. But I don't know how to do that with Aeson, aside probably from writing a custom parser and there must be a better way to do that obviously. Like maybe using language extension to derive (Generic, ToJSON, FromJSON) for addTask and removeTask etc...
EDIT. For all people that say "You can't serialize function".
Read the comments to an answer to this question.
Instance Show for function
That said, it's not possible to define Show to actually give you more
? detail about the function. – Louis Wasserman May 12 '12 at 14:51
Sure it is. It can show the type (given via Typeable); or it can show some of the inputs and outputs (as is done in QuickCheck).
EDIT2. Okay, I got that I can't have function name in serialization. But can this be done via template Haskell? I see that aeson supports serialization via template Haskell, but as newcomer to Haskell can't figure out how to do that.
Reading between the lines a bit, a recurring question here is, "Why can't I serialize a function (easily)?" The answer -- which several people have mentioned, but not explained clearly -- is that Haskell is dedicated to referential transparency. Referential transparency says that you can replace a definition with its defined value (and vice versa) without changing the meaning of the program.
So now, let's suppose we had a hypothetical serializeFunction, which in the presence of this code:
foo x y = x + y + 3
Would have this behavior:
> serializeFunction (foo 5)
"foo 5"
I guess you wouldn't object too strenuously if I also claimed that in the presence of
bar x y = x + y + 3
we would "want" this behavior:
> serializeFunction (bar 5)
"bar 5"
And now we have a problem, because by referential transparency
serializeFunction (foo 5)
= { definition of foo }
serializeFunction (\y -> 5 + y + 3)
= { definition of bar }
serializeFunction (bar 5)
but "foo 5" does not equal "bar 5".
The obvious followup question is: why do we demand referential transparency? There are at least two good reasons: first, it allows equational reasoning like above, hence eases the burden of refactoring; and second, it reduces the amount of runtime information that's needed, hence improving performance.
Of course, if you can come up with a representation of functions that respects referential transparency, that poses no problems. Here are some ideas in that direction:
printing the type of the function
instance (Typeable a, Typeable b) => Show (a -> b) where
show = show . typeOf
-- can only write a Read instance for trivial functions
printing the input-output behavior of the function (which can also be read back in)
creating a data type that combines a function with its name, and then printing that name
data Named a = Named String a
instance Show (Named a) where
show (Named n _) = n
-- perhaps you could write an instance Read (Map String a -> Named a)
(and see also cloud haskell for a more complete working of this idea)
constructing an algebraic data type that can represent all the expressions you care about but contains only basic types that already have a Show instance and serializing that (e.g. as described in the other answer)
But printing a bare function's name is in conflict with referential transparency.
Make a data type for your functions and an evaluation function:
data TaskFunction = AddTask Task | RemoveTask String
deriving (Eq, Show, Generic, ToJSON, FromJSON)
eval :: TaskFunction -> Storage -> Storage
eval (AddTask t) = addTask t
eval (RemoveTask t) = removeTask t
changes = [AddTask (Task "1" "Description" [] []), RemoveTask "1"]
main = putStrLn . show $ foldl (\s c -> c s) s (eval <$> changes)
I would like to implement a type-parametrized function as per excersize on page 72 of the book (implement forall using filter):
def forallA[B <: A](xs:List[A])(f:A => B) : List[B] = {
xs.filter(x => true) match {
case Nil => Nil
case y :: ys => f(y) :: forallA(ys)(f)
}
}
However, the compiler(2.9.1) complains about the type A being undefined. Clearly that should not be the case, since multiple examples in the same book use this syntax. The issue can be cured by changnig the function type parameter to [A, B <: A]. Am I doing something wrong, or is it again, a terrific change in Scala's syntax specification? If so, I am, frankfully, tired of bombing SO with such stupid questions on every second excersize. Could anyone recommend a book that clearly reflects the current order of things?
You already gave the answer: If you want to bound the type parameter B with another type parameter A, you have to add this to the list of type parameters:
def forall[A, B <: A](...)(...) = ...
Else you are referring to something undefined. Maybe it helps if you think of type parameters like usual (method) parameters. How should something like the following compile:
def add(x: Int) = x + y
Here the parameter y is undefined, just like in your case A was undefined.
Following up on How to make a record from a sequence of values, how can you write a defrecord constructor call and assign the fields from a Map, leaving un-named fields nil?
(defrecord MyRecord [f1 f2 f3])
(assign-from-map MyRecord {:f1 "Huey" :f2 "Dewey"}) ; returns a new MyRecord
I imagine a macro could be written to do this.
You can simply merge the map into a record initialised with nils:
(merge (MyRecord. nil nil nil) {:f1 "Huey" :f2 "Dewey"})
Note that records are capable of holding values stored under extra keys in a map-like fashion.
The list of a record's fields can be obtained using reflection:
(defn static? [field]
(java.lang.reflect.Modifier/isStatic
(.getModifiers field)))
(defn get-record-field-names [record]
(->> record
.getDeclaredFields
(remove static?)
(map #(.getName %))
(remove #{"__meta" "__extmap"})))
The latter function returns a seq of strings:
user> (get-record-field-names MyRecord)
("f1" "f2" "f3")
__meta and __extmap are the fields used by Clojure records to hold metadata and to support the map functionality, respectively.
You could write something like
(defmacro empty-record [record]
(let [klass (Class/forName (name record))
field-count (count (get-record-field-names klass))]
`(new ~klass ~#(repeat field-count nil))))
and use it to create empty instances of record classes like so:
user> (empty-record user.MyRecord)
#:user.MyRecord{:f1 nil, :f2 nil, :f3 nil}
The fully qualified name is essential here. It's going to work as long as the record class has been declared by the time any empty-record forms referring to it are compiled.
If empty-record was written as a function instead, one could have it expect an actual class as an argument (avoiding the "fully qualified" problem -- you could name your class in whichever way is convenient in a given context), though at the cost of doing the reflection at runtime.
Clojure generates these days a map->RecordType function when a record is defined.
(defrecord Person [first-name last-name])
(def p1 (map->Person {:first-name "Rich" :last-name "Hickey"}))
The map is not required to define all fields in the record definition, in which case missing keys have a nil value in the result. The map is also allowed to contain extra fields that aren't part of the record definition.
As mentioned in the linked question responses, the code here shows how to create a defrecord2 macro to generate a constructor function that takes a map, as demonstrated here. Specifically of interest is the make-record-constructor macro.