OPS5 rulebases may be readily converted into KnowledgeWorks rulebases. The main OPS5 forms needing conversion are:
(literalize employee name father-name mother-name)
(def-kb-struct employee name father-name mother-name)
(strategy lex)
(defcontext ops5 :strategy (lex specificity))
(strategy mea)
(defcontext ops5 :strategy (mea lex specificity))
In OPS5 you cannot have different conflict resolution strategies for different sets of rules. The KnowledgeWorks context mechanism for passing control is much clearer and more powerful than, for instance, the use of the MEA strategy as sole control mechanism in OPS5.
(p recognize-pair
(employee ^name <parent>)
(employee ^name <child> ^mother-name <parent>)
-->
(make pair))
(defrule recognize-pair :forward
(employee ? name ?parent)
(employee ? name ?child mother-name ?parent)
-->
(assert (pair ?)))
As an extended example below are given some OPS5 rules from the Monkey and Banana problem (see Examples):
(strategy mea)
(literalize monkey
name at on holds)
(literalize object
name at weight on)
(literalize goal
status type object to)
(literalize start)
(p mb1
(goal ^status active ^type holds ^object <w>)
(object ^name <w> ^at <p> ^on ceiling)
-->
(make goal ^status active ^type move ^object ladder
^to <p>))
(p mb4
{(goal ^status active ^type holds ^object <w>) <goal>}
(object ^name <w> ^at <p> ^on ceiling)
(object ^name ladder ^at <p>)
{(monkey ^on ladder ^holds nil) <monkey>}
-->
(write (crlf) Grab <w>)
(modify <goal> ^status satisfied)
(modify <monkey> ^holds <w>))
(p mb8
(goal ^status active ^type move ^object <o> ^to <p>)
(object ^name <o> ^weight light ^at <> <p>)
-->
(make goal ^status active ^type holds ^object <o>))
In KnowledgeWorks this could be:
(defcontext ops5 :strategy (mea lex specificity))
(def-named-kb-class monkey ()
((at :initform nil)
(on :initform nil)
(holds :initform nil)))
(def-named-kb-class object ()
((at :initform nil)
(weight :initform nil)
(on :initform nil)))
(def-kb-struct goal status type object to)
(def-kb-struct start)
(defrule mb1 :forward
:context ops5
(goal ? status active type holds object ?w)
(object ? name ?w at ?p on ceiling)
-->
(assert (goal ? status active type move object ladder
to ?p)))
(defrule mb4 :forward
:context ops5
(goal ?g status active type holds object ?w)
(object ? name ?w at ?p on ceiling)
(object ? name ladder at ?p)
(monkey ?m on ladder holds nil)
-->
((format t "~%Grab ~S" ?w))
(assert (goal ?g status satisfied))
(assert (monkey ?m holds ?w)))
(defrule mb8 :forward
:context ops5
(goal ? status active type move object ?o to ?p)
(object ? name ?o weight light at ?q)
(test (not (eq ?q ?p)))
-->
(assert (goal ? status active type holds object ?o)))