Short answer: no, it's not possible. The Rete network is not
reentrant in this way. Using queries on the left-hand-side of a rule
is already a delicate operation; using multiple recursive ones is
definitely not workable.
Longer answer: this isn't the right way to solve this kind of problem
in Jess, anyway. There's an example called "stack.clp" that ships
with Jess that shows one approach to blocks-world problems; the rules
in that file can clear off arbitrary source and target blocks when
the goal is to move a source block onto a target block.
Queries are a "cheat" intended mostly for reporting; they're a way
for procedural code -- mainly Java code -- to collect the results of
prior computation.
On Apr 12, 2007, at 6:18 AM, spielc wrote:
Hello it's me again!
I have another problem i need some help with.
I have the following facts in my database:
(deffacts initial-data
(on (x a) (y b))
(on (x b) (y c))
(on (x c) (y table))
)
I have the following rule:
(defrule put_on
"rule to put x on y"
(goal {x != y} (y ?goal_y) (x ?goal_x))
(goal {x != table})
?on <-(on (x ?goal_x) (y ?myy))
?goal <- (goal (x ?goal_x) (y ?goal_y))
(test (strips_clear ?goal_x))
(test (strips_clear ?goal_y))
=>
(retract ?goal)
(retract ?on)
(assert (on (x ?goal_x) (y ?goal_y)))
(assert (move (x ?x) (y ?myy) (z ?y)))
)
And i have the following function and query:
(defquery qry_clear
"comment"
(declare (variables ?x))
(on (y ?x) (x ?myx))
)
(deffunction strips_clear (?x)
"check if x is clear. means that nothing is ontop of x"
(if (eq ?x table) then
(return TRUE)
else
(bind ?result (count-query-results qry_clear (sym-cat ?x)))
(if (= ?result 0) then
(return TRUE)
else
(bind ?result (run-query* qry_clear ?x))
(?result next)
(bind ?resultx (?result getSymbol myx))
(?result close)
(bind ?tmp (str-cat "(on (x " ?resultx ") (y " ?x "))"))
(printout t ?tmp crlf)
;(return FALSE)
(strips_clear ?resultx)
(retract-string ?tmp)
(assert-string (str-cat "(on (x " ?resultx ") (y
table))"))
(assert-string (str-cat "(move (x " ?resultx ") (y " ?x
") (z
table))"))
)
)
)
What the function should do is, check if there is something "ontop"
of the
given parameter and if there is actually something ontop, it should
get
removed and put on the table (yep it's the famous blocks
world ;) ). That is
indicated with a fact in the db. E.g. (on (x a) (y b)) means that a
is ontop
of b. If something is ontop of the parameter the function is called
recursively to check if something is ontop of that particular
parameter.
The problem i'm facing now is when i actually have a recursive call
of the
function (bind ?resultx (?result getSymbol myx)) fails with the
message: The
cursor is before the first row; you must call next() before
accessing query
result . It works fine if i don't have a recursive call. Isn't it
possible
to achieve this bahaviour?
Regards and thanks in advance,
Christoph
--
View this message in context: http://www.nabble.com/Queries-and-
recursive-functions-tf3564625.html#a9956616
Sent from the Jess mailing list archive at Nabble.com.
--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users
[EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify owner-jess-
[EMAIL PROTECTED]
--------------------------------------------------------------------
---------------------------------------------------------
Ernest Friedman-Hill
Advanced Software Research Phone: (925) 294-2154
Sandia National Labs FAX: (925) 294-2234
PO Box 969, MS 9012 [EMAIL PROTECTED]
Livermore, CA 94550 http://www.jessrules.com
--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------