LispによるProlog
処理系の記述例

;;;
;;; c:\\program files\\acl62\\prolog.cl
;;;



(defun mb (v d) (list v d)) 

(defun ab (pve d bs)   (if (eq '?_ pve)     bs     (cons (mb pve d) bs)))
(defun fb (pve b) (unless (eq '?_ pve) (assoc pve b)))
(defun ek (b) (first b))
(defun ev (b) (second b))
(defun v-p (e) (and (symbolp e) (eql (char (symbol-name e) 0) #\?)))
(defun e-p (p d) (and (atom p) (atom d) (not (v-p p)) (not (v-p d))))
(defun r-p (p d) (and (listp p) (listp d)))
(defun u-as (p1 p2 bs) (if (eql p1 p2) bs 'fail))
(defun u-ps (p1 p2 bs)   (let ((r (unify (first p1) (first p2) bs)))    (if (eq 'fail r)      'fail      (unify (rest p1) (rest p2) r))))
(defun u-v (p1 p2 bs)   (let ((b (fb p1 bs)))    (if b      (unify (ev b) p2 bs)      (if (insidep p1 p2 bs)       'fail       (ab p1 p2 bs)))))
(defun insidep (v e bs) (if (equal v e) nil (inside-or-equal-p v e bs)))
(defun inside-or-equal-p (v e bs)   (cond ((equal v e) t)       ((and (atom e) (not (v-p e))) nil)       ((v-p e)        (let ((b (fb e bs)))         (when b (inside-or-equal-p v (eb b) bs))))       (t (or (inside-or-equal-p v (first e) bs) (inside-or-equal-p v (rest e) bs)))))
(defun unify (p1 p2 &optional bs)   (cond ((e-p p1 p2) (u-as p1 p2 bs))       ((v-p p1) (u-v p1 p2 bs))       ((v-p p2) (u-v p2 p1 bs))       ((r-p p1 p2) (u-ps p1 p2 bs))       (t 'fail)))
(setf *rs* nil *al* nil)
(defmacro :- (c &optional a)   `(length (push (list (car ',c) (cons (cdr ',c) ',a)) *rs*)))
(defun get-r (r)   (do ((l *rs* (cdr l))      (w))      ((null l) (reverse w))    (if (eql r (first (car l))) (push (car (rest (car l))) w))))
;;;(get-r 'c) ;;;
(defun vs-in (e)   (if (atom e)     (if (v-p e) (list e)) (union (vs-in (car e)) (vs-in (cdr e)))))
(defun c-vs1 (r) (setf *al* (mapcar #'(lambda (v) (list v (gensym "?"))) (vs-in r))))
(defun c-vs2 (r)   (cond ((null r) nil)       ((and (atom r) (v-p r)) (second (assoc r (reverse *al*))))       ((atom r) r)       (t (cons (c-vs2 (car r)) (c-vs2 (cdr r))))))
(defun c-vs3 (r) (c-vs1 r) (c-vs2 r))
(defun ps (p as bs)   (mapcan #'(lambda (r) (let ((re (unify as (car r) bs)))      (when (not (eql re 'fail))         (if (not (null (cdr r))) (pr (cdr r) re) (list re)))))      (mapcar #'c-vs3 (get-r p))))
(defun pr (expr &optional binds)   (case (car expr)     (and (p-and (reverse (cdr expr)) binds))     (or (p-or (cdr expr) binds))     (not (p-not (cadr expr) binds))     (t (ps (car expr) (cdr expr) binds))))
(defun p-and (clauses binds)   (if (null clauses)      (list binds)    (mapcan #'(lambda (b) (pr (car clauses) b)) (p-and (cdr clauses) binds))))
(defun p-or (clauses binds) (mapcan #'(lambda (c) (pr c binds)) clauses))
(defun p-not (clause binds) (unless (pr clause binds) (list binds)))
(defun i-v (v l)   (let* ((a1 (assoc v l)) (a2 (assoc (second a1) l)) (a3 (second a2)))    (if a3 (format t "~%~a <----- ~a" v a3))))
(defun i-vs (l)   (do ((lst (reverse (vs-in l)) (cddr lst)))      ((null lst))    (i-v (car lst) l)))
(defun is-vs (l)   (do ((lst l (cdr lst)))      ((null lst))    (print '***************************) (i-vs (car lst))))
;;; ;;; (get-answer '(f ?x ?y)) ;;; (get-answer '(si ?x ?y)) ;;; (defun get-answer (query)   (let ((lst (pr query)))    (format t "~%***** Your query is ~a." query) (is-vs lst)))
;;; ;;; 宣言的知識例 ;;; (:- (p d n)) (:- (p d de)) (:- (m d)) (:- (f ?x ?y) (and (p ?x ?y) (m ?x))) (:- (= ?x ?x)) (:- (si ?x ?y) (and (p ?z ?x) (p ?z ?y) (not (= ?x ?y)))) ;;; ;;;***** Your query is (f ?x ?y). ;;;*************************** ;;;?x <----- d ;;;?y <----- de ;;;*************************** ;;;?x <----- d ;;;?y <----- n ;;;nil ;;; ;;;***** Your query is (si ?x ?y). ;;;*************************** ;;;?x <----- de ;;;?y <----- n ;;;*************************** ;;;?x <----- n ;;;?y <----- de ;;;nil
トップページに戻る