2015-09-25 1 views
0

J'ai lu here comment appeler une fonction python sur la règle lhs d'une séquence.Fonction Python dans la règle LHS of CLIPS appelée plusieurs fois - comment attendre qu'une variable contienne une valeur?

Maintenant, j'ai la règle suivante:

(defrule python_func_lhs "comment me" 
    (object (is-a clips_TEST_CLASS) (some_slot ?some_slot_value)) 
    (test (eq (python-call python_print (str-cat "some_slot: " ?some_slot_value)) TRUE)) 
    => 
    ;(assert (do_something)) 
) 

Mon problème est que la fonction python est appelé deux fois, d'abord l'impression

some_slot: néant

puis

some_slot: some_slot_value

Il semble que la deuxième partie de la règle contenant la fonction python ne pas « attendre » pour la première partie de la règle LHS à apparier.

Comment puis-je faire en sorte que les clips n'appellent la fonction python qu'une seule fois, une fois que la première partie de la règle LHS a été mise en correspondance? En d'autres termes, je souhaite attendre que la variable ?some_slot_value ait une valeur.

Si possible, je voudrais éviter de créer plusieurs règles et d'utiliser des «faits de contrôle».

+0

Qu'est-ce que Jess a à voir avec cela? – laune

+0

@laune la question n'est pas spécifique à pyclips. En jess, il devrait aussi être possible d'appeler une fonction java sur les lhs d'une règle. Mais vous avez raison, je vais reformuler la question ou supprimer la balise. – stackoverflowwww

+0

Je viens d'essayer '(deffacte someData (Data (obj (new String" A "))))' et '(defrule find? Data <- (Data (obj? A)) (test (eq (call? une longueur) 1)) => (printout t "trouver exécuté" crlf)) 'dans Jess et ça marche bien. – laune

Répondre

2

Différents moteurs de règles ont différents moyens de spécifier quand les modifications d'objet sont terminées, mais généralement lorsque vous apportez plusieurs modifications distinctes à un objet, le processus de correspondance de modèle sera invoqué une fois pour chaque modification. Vous avez inclus un fragment de code, pas un exemple reproductible, dans votre question, donc je ne peux que deviner la cause de votre problème, mais probablement ce que vous faites est de créer l'objet et ensuite de le modifier dans une étape séparée. La correspondance de modèle est retardée lors de la création d'un objet jusqu'à ce que tous les remplacements d'emplacement aient été traités. De même, lorsque vous modifiez un objet, vous pouvez utiliser la fonction modify-instance pour regrouper une collection de modifications. Si vous devez retarder le filtrage de plusieurs appels de fonction, vous pouvez utiliser la fonction pattern-match-delay.

CLIPS> 
(defclass clips_TEST_CLASS 
    (is-a USER) 
    (slot some_slot)) 
CLIPS>  
(definstances initial 
    (i1 of clips_TEST_CLASS (some_slot some_slot_value))) 
CLIPS> 
(deffunction pcall (?v) (printout t ?v crlf) TRUE) 
CLIPS> 
(defrule python_func_lhs 
    (object (is-a clips_TEST_CLASS) (some_slot ?some_slot_value)) 
    (test (pcall (str-cat "some_slot: " ?some_slot_value))) 
    =>) 
CLIPS> (reset) 
some_slot: some_slot_value 
CLIPS> (make-instance i2 of clips_TEST_CLASS (some_slot some_other_value)) 
some_slot: some_other_value 
[i2] 
CLIPS> (make-instance i3 of clips_TEST_CLASS) 
some_slot: nil 
[i3] 
CLIPS> (send [i3] put-some_slot another_value) 
some_slot: another_value 
another_value 
CLIPS> 
(object-pattern-match-delay 
    (make-instance i4 of clips_TEST_CLASS) 
    (send [i4] put-some_slot still_another_value)) 
some_slot: still_another_value 
still_another_value 
CLIPS> (modify-instance [i4] (some_slot value)) 
some_slot: value 
TRUE 
CLIPS> 
+0

La prochaine fois je vais donner un exemple complet. Vous avez repéré le problème correctement - merci de partager le savoir-faire de vos clips sur SO – stackoverflowwww