Programmation des Systèmes Experts James L. Crowley Deuxième Année ENSIMAG Deuxième Semestre 2000/2001 TD 4 : 20 avril 2001 Exercice : L'objet de cet exercice est de réaliser un système de schémas permettant de répondre aux questions concernant les pages html. Les pages sont décrites par un arbre d objets généré par un système de règles. Les objets représentent les composants syntaxiques des pages. Les réponses sont générées par des "handlers" des objets. À fin d éviter les complications dans les règles, certains conventions syntaxique sont imposé sur la structure des pages html. Ces conventions peuvent êtres éliminés par un système de règle plus complexe, mais un tel système n est pas le but de cet exercice. Soit la définition de la classe «page» : (defclass page (is-a USER (role concrete (pattern-match reactive (slot file-name (create-accessor read-write (slot head (create-accessor read-write (slot body (create-accessor read-write (message-handler what-is-title (message-handler where-is-page (message-handler Get-level1-headings (message-handler Get-Hrefs Définir une classe pour head avec les slots «title» et «base». Faire une exemple de head avec (make-instance [page] of page (make-instance [head] of head (page "page.html"(title "This is a sample html page"(base "http://www-prima.imag.fr/" (send [page] put-head [head] Définir une classe body avec le les multislots «input» «H1s», «H2s», «HREFs» et «Ps». Faire un exemple de body avec (make-instance [body] of body (page "page.html"(h1 "Sample level 1 header"(ps [T1]
(send [page] put-body [body] Le message-handler «what-is-title» a la forme : (defmessage-handler page what-is-title ( (send?self:head get-title Le message-handler «where-is-page» return la valeur de «base» stocké en «head». Définir et tester le message handler «where-is-page». Les règles suivantes (ENSI2.SE.TD4.clips peuvent être utilisé pour lire le contenu d un fichier. ;; ;; defclass page ;; (defclass page (is-a USER (role concrete (pattern-match reactive (slot file-name (create-accessor read-write (slot head (create-accessor read-write (slot body (create-accessor read-write (defclass head (is-a USER (role concrete (pattern-match reactive (slot page (create-accessor read-write (slot title (create-accessor read-write (slot base (create-accessor read-write (defclass body (is-a USER (role concrete (pattern-match reactive (multislot H1s (create-accessor read-write (multislot H2s (create-accessor read-write (multislot Ps (create-accessor read-write (multislot HREFs (create-accessor read-write (defclass str "used for H1s, H2s and Ps" (is-a USER (role concrete (pattern-match reactive (slot text (create-accessor read-write 2
(defclass HREF (is-a USER (role concrete (pattern-match reactive (slot url (create-accessor read-write (slot ref (create-accessor read-write (deffacts tags (tags "<HTML>" "</HTML>" "<HEAD>" "</HEAD>" "<TITLE>" "</TITLE>" "<BASE>" "</BASE>" "<BODY>" "</BODY>" "<P>" "</P>" "<H1>" "</H1>" "<H2>" "</H2>" "<A" "</A>" ">" ;; regle d'ouverture et lecture du fichier html (defrule init (initial-fact (printout t "File Name? " (bind?file (read (assert (file-name?file (assert (file?file =(open?file data "r" (defrule no-file?f <- (file?file FALSE (retract?f (printout t?file " not found." crlf 3
(defrule read-line (declare (salience -10?f <- (file?file TRUE (retract?f (bind?in (readline data (printout t?in crlf (if (eq?in EOF then (assert (eof else (assert (line?in (assert (file?file TRUE (assert (file?file TRUE (defrule eof?f <- (file?file TRUE?eof <- (eof (retract?f?eof (close data ;; ce regle detecte les tags (defrule detect-tag (declare (salience 10?L<- (line $?start?str&:(stringp?str $?end (tags $??tag $? (test (str-index?tag?str (retract?l (bind $?list (parse?tag?str (printout t "Parse " $?list crlf (assert (line $?start $?list $?end (defrule add-line?l <- (line $?line?p <- (page $?page (retract?l?p (assert (page (create$ $?page $?line 4
Les instances de «pages» et «head» sont crée par les règles (defrule make-page (declare (salience 10 (file?file TRUE?page <- (page $?before HTML $?after (retract?page (assert (page $?before $?after (make-instance of page (file-name?file (defrule make-head (declare (salience 10?P <- (object (is-a page (file-name?file (file?file TRUE?page <- (page $?before HEAD $?head-stuff /HEAD $?after (retract?page (assert (page $?before $?after (assert (head $?head-stuff (bind?head (make-instance of head (page?page (send?p put-head?head (defrule make-title (declare (salience 10?H <- (object (is-a head?head <- (head $?before TITLE?title-str /TITLE $?after (retract?head (assert (head $?before $?after (send?h put-title?title-str (defrule delete-head?h<-(head (retract?h (defrule make-body (declare (salience 10?P <- (object (is-a page(file-name?file (file?file TRUE?page <- (page $?before BODY $?head-stuff /BODY $?after 5
(retract?page (assert (page $?before $?after (assert (body $?head-stuff (bind?body (make-instance of body (send?p put-body?body (defrule make-h1 (declare (salience 10?H <- (object (is-a body (H1s $?h1?body <- (body $?before H1?h1-str /H1 $?after (retract?body (assert (body $?before $?after (bind?new-h1 (make-instance of str (text?h1-str (send?h put-h1s (create$ $?h1?new-h1 (defrule make-p-text (declare (salience 10?H <- (object (is-a body (Ps $?P?body <- (body $?before P?P-str /P $?after (retract?body (assert (body $?before $?after (bind?new-p (make-instance of str (text?p-str (send?h put-ps (create$ $?P?new-P Ajouter les règles de lire le «title» et «base» d un «head». Ajouter une règle de créer un body. 6