-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterpreter.lisp
96 lines (72 loc) · 3.07 KB
/
interpreter.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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
;;;;interpreter.lisp
(in-package :lambda.interpreter)
;; Evaluating here means reducing in an environment. Lambda calculus does not
;; have environments per se, so here an environment is a list of assignments of
;; variables to λ terms.
;; For a non-reducing version use lambda.substitution:^substitute-environment.
(defun ^eval (term environment
&key (use-reduction-strategy '^reduce))
(funcall use-reduction-strategy
(^substitute-environment term environment)))
(defun ^eval-normal (term environment)
(^eval term environment :use-reduction-strategy '^reduce-normal))
;;; Catching some infinite loops.
;; Experiments with a notion of equality for the eventually self-evaluating
;; functions (loops longer than 1 step possible).
;;
;; There are several possibilities here, variating on the substitution steps
;; and/or reduction steps. Below I explore fully substituting and using
;; ^reduce-step and ^reduce-step-catch-loop.
(defun ^eval-step (term &optional environment)
"When the environement is NIL, this is just ^reduce-step."
(^reduce-step (^substitute-environment term environment)))
(defun ^eval-normal-steps (n term environment
&aux (temp (^substitute-environment
term environment)))
(loop for i from 1 to n
do (setf temp (^reduce-normal-step temp)))
temp)
(defun ^eval-catch-loop (term environment ; => ^term
&key (max-steps NIL))
"Lazy step"
(^reduce-catch-loop (^substitute-environment term environment)
:max-steps max-steps))
(defun ^eval-normal-catch-loop (term environment ; => ^term
&key (max-steps NIL))
(^reduce-normal-catch-loop (^substitute-environment term environment)
:max-steps max-steps))
;;; The interpreters for :lambda.repl
;; Creating the necessary environments
(defun simplify-in-assignment (assignment ; => assignment
&optional (environment (basic-combinators)))
(destructuring-bind (name . encoding) assignment
(assign name (^eval-normal-catch-loop encoding environment))))
(defun simplify-in-assignments (assignments ; => environment
&optional (environment (basic-combinators)))
(loop for assignment in assignments
collect (simplify-in-assignment assignment environment)))
(defun basic-encodings () ; => environment
(reverse (simplify-in-assignments (basic-combinators))))
(defun base-encodings () ; => environment
(append (basic-encodings)
(recursing-combinators)))
(defun church-encodings () ; => environment
(append (reverse
(simplify-in-assignments (church-arithmetic)
(append (church-arithmetic)
(basic-encodings))))
(base-encodings)))
(defun all-encodings () ; => environment
(append (reverse
(simplify-in-assignments
(lambda.encodings::barendregt-arithmetic)))
(church-encodings)))
;; An interpreter for encoded terms
(defun ^interpret (term environment
&key
(reduction #'^reduce-normal)
(decoding #'decode-encodings-in-term))
"The eval-print part of a repl."
(let ((answer (^eval term environment
:use-reduction-strategy reduction)))
(funcall decoding answer environment)))