Программно изменить слот фактов с помощью ClipsPy - PullRequest
0 голосов
/ 29 декабря 2018

Как изменить факт шаблона в CLIPS с помощью ClipsPy.

Я попытался переназначить значение слота и отправить модификацию в процедуре clips.build (см. Функцию py_modify ниже), которая не работала.

Это файл .clp

;; KB.clp
(deftemplate t
    (slot s_1 (type SYMBOL)))

(defrule main-intent
    (initial-fact)
    =>
    (assert (t (s_1 v_1)))
)

(defrule rule_1
    ?p<-(t (s_1 ?v))
    =>
    (printout t"BEFORE"crlf) (py_pfact)
    (py_modify ?p)
    (printout t"AFTER"crlf) (py_pfact)
)

Это файл python ..

# run.py
import clips

clips_env = clips.Environment()

def py_pfact():
    for fact in clips_env.facts():
        print(fact)

def py_modify(p):
    print("--modifying",p["s_1"])
    p["s_1"] = "v_2"  # Try 1
    clips.build("(modify "+str(p.index)+ " (s_1 v_2)") #Try 2

clips_env.define_function(py_pfact)
clips_env.define_function(py_modify)

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

Выход составляет

 BEFORE
(initial-fact)
(t (s_1 v_1))
--modifying v_1
AFTER
(initial-fact)
(t (s_1 v_1))

Я ожидаю, что слот s_1 будет изменен на v_2 с v_1, но это не так.

1 Ответ

0 голосов
/ 30 декабря 2018

Метод environment.build предназначен для строительных конструкций (defrule, deftemplate и т. Д.) Внутри двигателя.Чтобы выполнить код CLIPS, вам нужно использовать environment.eval.

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

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 предоставляет команду modify, которая делает то же самое: отнимает факт и утверждает его с помощьюновое значение.Тем не менее, его нельзя использовать через environment.eval, так как фактические индексы нельзя использовать через API.Если вы хотите изменить факт в правиле, лучше использовать команду modify напрямую.

(defrule rule_1
  ?p <- (t (s_1 ?v))
  =>
  (modify ?p (s_1 v_2)))
...