®, the Rule Engine for the Java TM Platform
Author
Wolfgang Laun
Wolfgang Laun a-t thalesgroup com
Name: Acting Facts
Intent: Put part of a rule's action into a fact.
Motivation:
Systematic use of inline function definitions in a fact permits you have
mappings of function codes to actions as a collection of facts. Matching
a function code fires a generic rule that calls the function that is kept with the code.
Applicability: Parsers, automata.
Participants:
Basic ingredients are facts and lambda expressions. The "inline" definition of actions as lambda expressions either requires Jess 71a2 or later or the Jess command extension lcall for calling a lambda expression (see AddingCommandsToJess).
Sample code:
;; Implements a simple interpreter for postfix expressions.
;; Operators of a class are handled by a generic rule. The
;; actual processing is stored in an operation definition fact.
;;
(clear)
;; Operator definitions
;;
(deftemplate Operator
"Defines the relation between an operator symbol and its function."
(slot symbol (type SYMBOL))
(slot function (type ANY)))
(deftemplate UnaryOperator extends Operator)
(deftemplate BinaryOperator extends Operator)
(deffacts bin-ops
"Binary operator definitions"
(BinaryOperator (symbol add) (function (lambda (?a ?b) (+ ?a ?b))))
(BinaryOperator (symbol sub) (function (lambda (?a ?b) (- ?a ?b))))
(BinaryOperator (symbol mul) (function (lambda (?a ?b) (* ?a ?b))))
(BinaryOperator (symbol div) (function (lambda (?a ?b) (/ ?a ?b)))))
(deffacts un-ops
"Unary operator definitions"
(UnaryOperator (symbol neg) (function (lambda (?a) (- 0 ?a))))
(UnaryOperator (symbol sqr) (function (lambda (?a) (* ?a ?a)))))
(reset)
;; Processing input stream tokens
;;
(deftemplate Token
"A Token fact contains information about an input stream token."
(slot text (type STRING))
(slot pos (type INTEGER)))
(defglobal ?*nToken* = 0)
(deffunction getToken ( ?route )
(bind ?tok (read ?route))
(if (eq ?tok EOF) then
(return FALSE)
else
(assert (Token (text ?tok) (pos (++ ?*nToken*))))
(return TRUE)
)
)
;; Rule for binary operations
;;
(defrule binary-op
?op <- (Token (text ?op-text) (pos ?op-pos))
?func <- (BinaryOperator (symbol ?func-symbol & ?op-text) (function ?func-function))
?arg2 <- (Token (text ?arg2-text)
(pos ?arg2-pos &:(= ?arg2-pos (- ?op-pos 1))))
?arg1 <- (Token (text ?arg1-text)
(pos ?arg1-pos &:(= ?arg1-pos (- ?op-pos 2))))
=>
(retract ?op ?arg2 ?arg1)
(assert (Token (text (call ?func-function ?arg1-text ?arg2-text ))
(pos ?arg1-pos)))
(bind ?*nToken* ?arg1-pos)
)
;; Rule for unary operations
;;
(defrule unary-op
?op <- (Token (text ?op-text) (pos ?op-pos))
?func <- (UnaryOperator (symbol ?func-symbol & ?op-text) (function ?func-function))
?arg <- (Token (text ?arg-text)
(pos ?arg-pos &:(= ?arg-pos (- ?op-pos 1))))
=>
(retract ?op ?arg)
(assert (Token (text (call ?func-function ?arg-text ))
(pos ?arg-pos)))
(bind ?*nToken* ?arg-pos)
)
(open "postfix1.dat" pfd r)
(while (eq (getToken pfd) TRUE)
(run)
)
(close pfd)
|
Front Page |
Sandbox |
Recent Changes |
Powered by Friki |
Last Edited: 23 July 2007
|