Неравномерность изменения значения слота в шаблоне фактов CLIPS с использованием clipsPy - PullRequest
0 голосов
/ 01 января 2019

Я пытаюсь изменить шаблон факта из python, используя CLIPSPY.Он ведет себя странно, так как он изменяет слот в первый раз, но затем для следующего слота он не изменяет и даже не изменяет ранее измененное значение слота на что-то другое !!

Это файл python.

# run.py
import clips

clips_env = clips.Environment()

def py_modify_s1(p):
    p.retract()
    p["s_1"] = clips.Symbol("ABC") 
    p.assertit()

def py_modify_s2(p):
    p.retract()
    p["s_2"] = clips.Symbol("DEF") 
    p.assertit()

clips_env.define_function(py_modify_s1)
clips_env.define_function(py_modify_s2)

clips_env.load("KB.clp")
clips_env.reset()
clips_env.run()

Это файл clp.

(deftemplate t
        (slot s_1 (type SYMBOL) (default none))
        (slot s_2 (type SYMBOL) (default none))
)

(defrule rule_0
        (initial-fact)
        =>
        (assert (t))
)

(defrule rule_1
        ?p<-(t  (s_1 none) (s_2 none))
        =>
        (py_modify_s1 ?p)
        (facts)
)

(defrule rule_2
        ?p <- (t (s_1 ?x&~none) (s_2 none))
        =>
        (py_modify_s2 ?p)
        (facts)
)

(defrule rule_3
        ?p <- (t (s_1 ?x&~none) (s_2 ?y&~none))
        =>
        (printout t "All set")
        (facts)
)

Запуск того же файла клипа в оболочке CLIPS (замена py_modify на (modify ?p (s_1,ABC))) дает ожидаемый результат.Но при запуске из clipspy я получаю:

f-0     (initial-fact)
f-2     (t (s_1 ABC) (s_2 none))
For a total of 2 facts.
f-0     (initial-fact)
f-2     (t (s_1 ▒▒▒3wU) (s_2 none))
For a total of 2 facts.

Обратите внимание, что s_1 содержит некоторое значение мусора после запуска rule_2 и s_2 не изменяется только.В результате, rule_3 никогда не будет уволен.

1 Ответ

0 голосов
/ 02 января 2019

Оказывается, факты не могут быть изменены после утверждения через C (и, следовательно, Python) API.Единственный способ изменить факт - это отозвать исходный и утвердить новый.Глава 4.4.22 EnvPutFactSlot Расширенного руководства по программированию.

Единственный возможный способ, по-видимому, - убрать старый факт и утвердить новый с обновленными значениями.

def modify_fact(fact):
    """Modify a template fact."""
    fact.retract()

    new_fact = fact.template.new_fact()
    new_fact.update(dict(fact))  # copy over old fact slot values

    new_fact["s_1"] = clips.Symbol("v_2") 

    new_fact.assertit()

Я поднял эту проблему в обсуждение на форуме CLIPS.

...