simple pattern matching 1/2 simple pattern matching ; Solo patrones sin variables: (patmat1 '(a b)'(a b))=>T (defun patmat1 (patron lista) (cond ((and (null patron)(null lista)) t) ((and (eql (first patron)(first lista))) (patmat1 (rest patron)(rest lista)))) (t nil))) ; Admita utilizar comodines: (patmat2 '(a ? b ?)'(a c b a))=>T (defun patmat2 (patron lista) (cond ((and (null patron)(null lista)) t) ((is-? (first patron)) (patmat2 (rest patron)(rest lista))) ((and (eql (first patron)(first lista))) (patmat2 (rest patron) (rest lista)))) (t nil))) (defun is-? (v) (eql v '?)) 2/2 ; Admite además comodines de segmento (defun patmat3 (patron lista) (cond ((and (null patron)(null lista)) t) ((is-? (first patron)) (if (not (null lista)) (patmat3 (rest patron)(rest lista)))) ((is-* (first patron)) (or (patmat3 (rest patron) nil) ; toda la lista ; o de cualquier otro tamanyo (some #'(lambda (segmento) (patmat3 (rest patron) segmento)) (maplist #'(lambda (x) x) lista)))) ((and (eql (first patron)(first lista))) (patmat3 (rest patron) (rest lista)))) (t nil))) ; Para comprobar el tipo comodin (defun is-? (v) (eql v '?)) (defun is-* (v) (eql v '*)) 1 pattern matching (defun is-p (x) ;(consp nil)=>NIL (and (consp x) (not (member (first x) '(? *))))) 1/4 (defun is-? (x) (and (consp x) (eql (first x) '?))) (defun is-* (x) (and (consp x) (eql (first x) '*))) (defun 1st-var-pat (pat) (second (first pat))) (defun get-pred (p) (first (first p))) pattern matching 2/4 (defun patmat4 (patron lista sustitucion) (cond ((and (null patron)(null lista)) (add-lig :y :y sustitucion)) ((is-? (first patron)) (match-? patron lista sustitucion)) ((is-* (first patron)) (match-* patron lista sustitucion)) ((is-p (first patron)) (match-p patron lista sustitucion)) (t (and (eql (first patron)(first lista)) (patmat4 (rest patron) (rest lista) sustitucion))))) (defun match-? (patron lista sustitucion) (let* ((var (1st-var-pat patron)) (ligadura (get-lig var sustitucion))) (if ligadura ; si hay ligadura debe ser eql con first de lista y sigo (and (eql (first lista) (val-lig ligadura)) (patmat4 (rest patron)(rest lista) sustitucion)) ; si no hay ligadura, anyado una nueva y sigo adelante (patmat4 (rest patron)(rest lista) (add-lig var (first lista) sustitucion)) ))) (defun add-lig (var val subst) (defun val-lig (lig) (acons var val subst)) (cdr lig)) (defun get-lig (var subst) (assoc var subst)) 2 (defun val (var subst) (cdr (assoc var subst))) (defun match (patron lista) (patmat4 patron lista nil)) 3 4 pattern matching 3/4 pattern matching (defun match-* (patron lista sustitucion) (let* ((var (1st-var-pat patron)) (ligadura (assoc var sustitucion))) (if ligadura ; si hay lig. compruebo que el sufijo de la lista concuerde (let* ((sgto (val-lig ligadura)) (long (length sgto)) (lista-sgto (nthcdr long lista))) (and (equal (append sgto lista-sgto) lista) (patmat4 (rest patron) lista-sgto sustitucion))) ; si no la hay (or ; o la variable de segmento es nula (patmat4 (rest patron) lista (add-lig var nil sustitucion)) ; o concuerda con uno o mas elementos de lista (match-sto var patron lista sustitucion))))) 4/4 (defun match-sto (var patron lista sustitucion) (do* ((lst lista (rest lst)) sufijo prefijoInv result) ((or result (null lst)) result) (push (first lst) prefijoInv) (setq sufijo (rest lst)) (setq result (patmat4 (rest patron) sufijo (add-lig var (reverse prefijoInv) sustitucion))))) (defun match-p (patron lista sustitucion) (if (apply (get-pred patron) (list (first lista))) (patmat4 (rest patron) (rest lista) (add-lig (1st-var-pat patron) (first lista) sustitucion)))) 5 6