Facts and Simple querries with ordered facts
assert an ordered fact assert( person( "mark", "UK" ) )
return a list of one
list = person("mark", "UK") assert another fact assert( person( "mic", "UK" ) )
Returns a list of two, as $name is not bound
list = person( $name, "UK )
returns a list of 1, as $name is now bound
$name == "mark list = person( $name, "UK )
Compound querries with ordered facts
assert( likes( "mark", "beans" ) assert( likes( "mark", "pizza" ) assert( likes( "mark", "coke" ) assert( likes( "mic", "meat" ) assert( likes( "mic", "pizza" ) assert( likes( "mic", "fish" )
inline query, returns a list of 1, mic
list = person( $name, "UK ), likes( $name, "meat" )
The "likes" query acts as a correlated subquery, it is evaluated for each returned "person" row, $name handles the correlation.
Lets turn this into a named query - see its just like an existing drools query, except it takes a parameter:
query "who likes meat"($name) person( $name, "UK" ) likes( $name, meat ) end
We can use the above query in two ways
returns a list of 1
list = "who likes meat"( "mic" )
returns an empty list
list = "who likes meat"( "mark" )
Also returns a list of 1, as $name is not yet bound
list = "who likes meat"( $name )
Returns an empty list, as $name is now bound
$name = "mark" list = "who likes meat"( $name )
Nested Querries
so we can create "views" on compound querries.
query "favourite foods"($name, $location, $food ) person( $name, $location ) likes( $name, $food ) end assert( restaurant("meat hut", "UK", "meat") ) assert( restaurant("meat hut", "USA", "meat") ) assert( restaurant("pizza hut", "UK", "pizza") ) query "my restaurants"($personName, $restuarantName, $food) "favourite foods"($personName, $food, $location) restaurant($restaurantName, $location, $food) end
If no variables are needed for a correlated query you can just use a
"my restaurants"("mic", *, *)
returns a list of
"mic", "meat hut", "meat" "mic", "pizza hut", "pizza"
Querries with rules
So how does this work with rules?
rule "when hungry when Person( $name : name; hungry == true ) "my restaurants"( $name, $restuarantName, $food ) //notice $food and $location where not previous bound then send $name to $restuarantName to eat $food end
language changes to facilite prolog style usage of rules
'from' is ideal for iterating over collections return 'from' a function call. And ofcourse we turn function calls that return single values into a collection to do an iteration of one. However I thought it might be more declarative to add an = or an 'is' keyword.
$f = $dog.name
or possible
$f is $dog.name
but I think I prefer the first
Internally this would just use 'from', but it might be more declaratively understandable to allow the above. The other reason is it facilitates prolog style backward chaining, where you can use something like this in a rule:
c_to_f(C,F) :-
F is C 9 / 5 + 32.
C is an 'in' variable and F is an 'out' variable.
Further to this I thought it would be good to allow function calls, that are basically converted to evals
log($fact)
instead of
eval( log($fact) )
Comments