Techniques de programmation CLIPS
Transcription
Techniques de programmation CLIPS
Programmation des Systèmes Experts James L. Crowley Deuxième Année ENSIMAG Séance 12 : Deuxième Semestre 2002/2003 25 avril 2003 Techniques avancées en CLIPS Inclusion des fonctions extern dans CLIPS...........................2 Communications utilisant "eval" et "build" ............................7 Evaluation de fonctions par "eval".......................................... 8 Definitions dynamique avec a fonction "build"......................... 9 Definition dynamique de la Protocole de Communication.......... 11 exemple d'execution d'interpret......................................... 12 Regle de communication par message.................................. 12 Techniques avancées en CLIPS Séance 12 Inclusion des fonctions extern dans CLIPS CLIPS est un système ouvert ("Open System" en anglais) Il est écrit en C et distribué avec sa code source. Ceci rend facil l'inclusion de fonctions extern, écrit par l'utilisateur, dans l'environnement de l'interpret. L'extension de CLIPS est decrit dans le manual : Vol 2 : Advanced Programming Guide Pour ajouter une fonction extern il faut 1) compiler le fonction. 2) Ajouter une declaration de la fonction et ses parametres dans main.c 3) Inclure son code objet (fonction.o) dans le "make-file" et refaire le "make". Les fonctions sont declarés avec DefineFunction ou DefineFunction2 int int DefineFunction(functionName,functionType, functionPointer,actualFunctionName); DefineFunction2(functionName,functionType, functionPointer,actualFunctionName, functionRestrictions); char *functionName, functionType, *actualFunctionName; int (*functionPointer)(); char *functionRestrictions Exemple des declarations : UserFunctions() { /* Declare your C functions if necessary. */ extern double ma_fonc(); extern VOID *dummy(); /* Call DefineFunction to register user-defined functions. */ DefineFunction("fonc",'d',ma_fonc,"ma_fonc"); } 12-2 Techniques avancées en CLIPS Séance 12 Les paramètres de DefineFonction sont 1) La nom à utiliser dans l'interpreter CLIPS. Pas forcement le meme que le nom du fonction ecrite en "c". 2) Le type de resultat rendu par le fonction. (ici un double). 3) L'adresse de la fonction. 4) Une representation en chaine de caractere (STRING) de l'adresse de la fonction. Il est possible de declarer la fonction avec ses arguments en utilisant "DefineFunction2". int char int char DefineFunction2(functionName,functionType, functionPointer,actualFunctionName, functionRestrictions); *functionName, functionType, *actualFunctionName; (*functionPointer)(); *functionRestrictions Les premieres 4 arguments sont les memes que DefineFonction. Le cinquième est une chaine de caracteres decrivant les arguments. Cette chaine a le format : <min-args> <max-args> [<default-type> <types>*] Explications : <min-args> <max-args> : des entiers ou "*" Exemples : La communication entre deux processus CLIPS sur deux machines differents peut etre assurer par les procedures en C : transmet() et recoit(). La procedure "transmet()" permet de transmetre une chaine "message". On veut que sa nom en CLIPS soit "send_mess". Il return un code d'erreur ou NULL si le message est transmit. La procedure "recoit()" permet de recoit une chaine "message". On veut que sa nom en CLIPS soit "get_mess". Il return une chaine ou une code d'erreur. int transmet(char * message; ) {... } char * {... } recoit() 12-3 Techniques avancées en CLIPS Séance 12 Dans main.c : DefineFunction2(send-mess, 'i', transmet, "transmet", "11s"); DefineFunction(get-mess, 's', recoit, "recoit"); Les codes des types de retour sont : Return Code Return Type Expected a b c d f i j k l m n o s u v w x External Address Boolean Character Double Precision Float Single Precision Float Integer Unknown Data Type (Symbol, String, or Instance Name Expected) Unknown Data Type (Symbol or String Expected) Long Integer Multifield Unknown Data Type (Integer or Float Expected) Instance Name String Unknown Data Type (Any Type Expected) Void—No Return Value Symbol Instance Address Des codes de types pour les paramètres sont. Type Code Allowed Types a d e f g h i j k l m External Address Float Instance Address, Instance Name, or Symbol Float Integer, Float, or Symbol Instance Address, Instance Name, Fact Address, Integer, or Symbol Integer Symbol, String, or Instance Name Symbol or String Integer Multifield 12-4 Techniques avancées en CLIPS n o p q s u w x y z Séance 12 Integer or Float Instance Name Instance Name or Symbol Symbol, String, or Multifield String Any Data Type Symbol Instance Address Fact Address Fact address, Integer, or Symbol Dans le projet ESPRIT VAP II (1993 - 1995) on a utiliser CLIPS comme interpreter d'un système repartis sur 10 processeurs. Les fonctions de traitement etait inclus dans chaque CLIPS. La communication fut effectuer par sockets. Le prototcole de communication était définit dynamiquement par "eval" et "build". Le Système etait composé de 9 processus communiquant par socket. Une configuration typique etait : Supervisor High Bandwidth Data Messages Object Recognition Radio Modem Synch 3D Description M a i l b o x Left Image Description Right Image Description Image Acquisition and Processing Fixation Camera Controller Navigation Vehicle Controller Chaque processus avait l'architecture suivant : 12-5 Techniques avancées en CLIPS Séance 12 Interpretation Demons M A I L B O X Access Primitives (grouping) Model Predict Update CLIPS 5.1 Match Message Handler Process Parameters Processing Data Procedure Call Messages Standard Module Architecture Chaque module etait un noyau CLIPS dans lequel on a inclut les procedures specialisé en C. Le traitement etait un cycle des phases : get-data, transform, predict, match, update, demons Le côntrole, le traitement de messages, et les demons etait fais en CLIPS. Chaque type de message etait un "fonction" definit par "deffunction". Les messages etait traité par "eval". Le protocol de communication etait programmé dynamiquement utilisant "build". Un module pouver envoyer une message deffinisant un nouvelle commande a traiter. 12-6 Techniques avancées en CLIPS Séance 12 Communications utilisant "eval" et "build" Processus A programme processus B par message (deffunction foo ...) Module A Module B Processus B reception le nouvelle fonction "foo". Module A Module B (build (deffunction foo ...)) Processus A peut ensuite executer fonction foo par message a Procesus B (foo args) Module A Module B Processus B interpret the message ... Module A Module B ( eval (foo args)) .... et retourne un resultat. ( eval (foo args)) Module A Module B 12-7 Techniques avancées en CLIPS Séance 12 Evaluation de fonctions par "eval" (eval <string>) ou (eval <symbol_expression>) La fonction "eval" permet d'interprèter une expression comme si il a été tapé par l'utilisateur. L'expression peut être une chaine de caractères ou des symboles. exemple : CLIPS> (eval "(+ 3 4)") 7 CLIPS> (eval "(create$ a b c)") (a b c) CLIPS> ;; ;; exemple de eval avec un fonction. ;; CLIPS> (deffunction f (?a) (printout t "f(" ?a ") CLIPS> (f 1) f(1) = 16838 CLIPS> (eval "(f 2)") f(2) = 5758 CLIPS> = " (random) crlf)) Eval n'execute pas un fonction de definitions (ex.: defrule, deftemplate, declasse...) Pour les definitions, il faut utiliser "build". 12-8 Techniques avancées en CLIPS Séance 12 Definitions dynamique avec a fonction "build" (build <string>) ou (build <symbol_expression>) La fonction build permet l'interpretation d'une chaine de caractere contenant une definition CLIPS , (ex.: defrule, deftemplate, declasse...). build retourne TRUE si la definition a marché et FALSE s'il y a eu une erreur. ;; ;; ;; exemple de build CLIPS> (build "(deffunction g (?a) (return ?a)") TRUE CLIPS> (g whiz) whiz ;; qu'est ce passe si on fait ceci? CLIPS> g(whiz) g Une Probleme : les guillements dans une chaine de caractères Il faut les preceder les guillement par \ CLIPS> (build "(deffunction f (?a) (printout t \"f(\" ?a \") = \" (random) crlf )" ) TRUE CLIPS>(f 1) f(1) = 31051 CLIPS>(eval "(f 1)") Build permet des règles en CLIPS de construire d'autre règles. exemple : ;; ;; build d'un regle ;; (defrule regle-construit (a b c) => (printout " (a b c) existe " crlf) ) 12-9 Techniques avancées en CLIPS peut etre construit par : Séance 12 (build "(defrule regle-construit (a b c) => (printout t \" (a b c) existe \" crlf) )" ) Le chaine de caractère peut être composer par un ensemble de règles. Deux processus CLIPS communicant par Socket peut definir leur protocol de communication dynamiquement utilisant Build et Eval. Soit les fonction d'envoie et reception "send-mess" et "get-mess". On peut simuler send-mess et get-mess avec printout et readline. ;; ;; send-mess permet l'envoie d'une message par "socket" on simule send-mess ici avec printout (deffunction send_mess (?message) (printout ?message)) ;; get-mess recoit une message par socket. ;; On simule get-mess avec readline (deffunction get-mess () (printout t "Message? ") (return (readline))) ;; interrogation ;; reponse exemple : CLIPS> (send-mess "This is a test") This is a test CLIPS> (get-mess) Message? this is a test "this is a test" CLIPS> On peut interpreter les message par une fonction "interpret". (deffunction interpret () (eval (get-mess)) ) Exemple : CLIPS> (deffunction send-mess (?message) (printout t ?message crlf)) CLIPS> (deffunction get-mess () (printout t "Message? ") (return (readline))) ) 12-10 Techniques avancées en CLIPS Séance 12 CLIPS> (deffunction interpret () (eval (get-mess))) CLIPS> (interpret) Message? (assert (a b c)) <Fact-0> CLIPS> (facts) f-0 (a b c) For a total of 1 fact. CLIPS> Definition dynamique de la Protocole de Communication Avec "build" et "eval", des processus CLIPS repartis peut se definir leur protocole de communication dynamiquement. C.-a-d. Un processus CLIPS peut programmer un autre. Si un message commence par ""(def..." on appel "build" sinon "eval". (deffunction interpret () (bind ?mess (get-mess)) (bind ?sub (sub-string 2 4 ?mess)) (if (eq ?sub "def") then (build ?mess) else (eval ?mess)) ) On peut verifier que la message est a "interpreter" en testant si le premiere caractere est un "(". (deffunction interpret () (bind ?mess (get-mess)) (if (neq (sub-string 1 1 ?mess) "(") then (printout t "message : " ?mess crlf) (return TRUE) else (bind ?sub (sub-string 2 4 ?mess)) (if (eq ?sub "def") then (build ?mess) else (eval ?mess)) ) ) 12-11 Techniques avancées en CLIPS Séance 12 exemple d'execution d'interpret CLIPS> (interpret) Message? this is a test message : this is a test CLIPS> (interpret) Message? (assert (this is a test)) <Fact-0> CLIPS> (facts) f-0 (this is a test) For a total of 1 fact. CLIPS> (interpret) Message? (deftemplate A (slot b) (slot c)) TRUE CLIPS> (interpret) Message? (assert (A (b "test"))) <Fact-1> CLIPS> (facts) f-0 (this is a test) f-1 (A (b "test") (c nil)) For a total of 2 facts. CLIPS> Regle de communication par message On peut avoir une regle qui recoit et interpret les messages : (defrule get-message ?go <- (go) (not (stop)) => (retract ?go) (assert (go)) (send-mess (interpret)) ) CLIPS> (run) Message? this is a test message : this is a test TRUE Message? (assert (this is a test)) <Fact-19> Message? (deffunction stop () (assert (stop))) TRUE Message? (deffunction f1 (?x ?y) (+ ?x ?y)) TRUE Message? (f1 1 2) 3 Message? (deffunction f2 (?x ?y) (* ?x ?y)) TRUE Message? (f2 2 3) 6 Message? (stop) <Fact-10> CLIPS> 12-12 Techniques avancées en CLIPS Séance 12 12-13