-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpattern-matching.lisp
46 lines (33 loc) · 1.22 KB
/
pattern-matching.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
(in-package #:cl-prolog)
;; Pattern-matching code
(defconstant fail nil
"Indicates pat-match failure")
(defconstant no-bindings '((t . t))
"Indicates pat-match success, with no variables.")
(defun variable-p (x)
"Is x a variable (a symbol beginning with '?')?"
(and (symbolp x) (equal (char (symbol-name x) 0) #\?)))
(defun get-binding (var bindings)
"Find a (variable . value) pair in a binding list."
(assoc var bindings))
(defun binding-val (binding)
"Get the value part of a single binding."
(cdr binding))
(defun lookup (var bindings)
"Get the value part (for var) from a binding list."
(binding-val (get-binding var bindings)))
(defun extend-bindings (var val bindings)
"Add a (var .value) pair to a binding list."
(cons (cons var val)
;; Once we add a "real " binding,
;; we can get rid of the dummy no-bindings
(if (equal bindings no-bindings)
nil
bindings)))
;; I changed eq for equal in the last function.
(defun match-variable (var input bindings)
"Does VAR match input? Uses (or updates) and returns bindings."
(let ((binding (get-binding var bindings)))
(cond ((not binding) (extend-bindings var input bindings))
((equal input (binding-val binding)) bindings)
(t fail))))