Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/triska/lisprolog
Interpreter for a simple Lisp. Written in Prolog.
https://github.com/triska/lisprolog
interpreter lisp prolog
Last synced: 2 days ago
JSON representation
Interpreter for a simple Lisp. Written in Prolog.
- Host: GitHub
- URL: https://github.com/triska/lisprolog
- Owner: triska
- Created: 2014-09-12T16:23:52.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2023-02-22T23:24:12.000Z (almost 2 years ago)
- Last Synced: 2024-11-25T11:18:24.490Z (2 months ago)
- Topics: interpreter, lisp, prolog
- Language: Prolog
- Homepage: https://www.metalevel.at/lisprolog/
- Size: 8.79 KB
- Stars: 145
- Watchers: 7
- Forks: 13
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Interpreter for a simple Lisp, written in Prolog
Some online books show how to implement simple "Prolog" engines in
Lisp. These engines typically assume a representation of Prolog
programs that is convenient from a Lisp perspective, and can't even
parse a single proper Prolog term. Instead, they require you to
manually translate Prolog programs to Lisp forms that are no longer
valid Prolog syntax. With this approach, implementing a simple "Lisp"
in Prolog is even easier ("Lisp in Prolog in zero lines"): Manually
translate each Lisp function to a Prolog predicate with one additional
argument to hold the original function's return value. Done. This is
possible since a function is a special case of a relation, and
functional programming is a restricted form of logic programming.Here is a bit beyond that: [**`lisprolog.pl`**](lisprolog.pl)
These 165 lines of Prolog code give you an interpreter for a simple
Lisp, *including* a parser to let you write Lisp code in its
natural form.Internally, Prolog [**Definite Clause
Grammars**](https://www.metalevel.at/prolog/dcg) are used for parsing
Lisp code, and
[semicontext notation](https://www.metalevel.at/prolog/dcg#semicontext)
is used to implicitly thread through certain arguments. This
Prolog feature is very similar to Haskell's monads.Read [**The Power of Prolog**](https://www.metalevel.at/prolog) for
more information about Prolog.Sample queries, using Scryer Prolog:
Append:
?- run(" \
\
(defun append (x y) \
(if x \
(cons (car x) (append (cdr x) y)) \
y)) \
\
(append '(a b) '(3 4 5)) \
\
", Vs).
Vs = [append,[a,b,3,4,5]].
Fibonacci, naive version:
?- time(run(" \
\
(defun fib (n) \
(if (= 0 n) \
0 \
(if (= 1 n) \
1 \
(+ (fib (- n 1)) (fib (- n 2)))))) \
(fib 24) \
\
", Vs)).
% CPU time: 6.414s
Vs = [fib,46368].
Fibonacci, accumulating version:
?- time(run(" \
\
(defun fib (n) \
(if (= 0 n) 0 (fib1 0 1 1 n))) \
\
(defun fib1 (f1 f2 i to) \
(if (= i to) \
f2 \
(fib1 f2 (+ f1 f2) (+ i 1) to))) \
\
(fib 250) \
\
", Vs)).% CPU time: 0.020s
Vs = [fib,fib1,7896325826131730509282738943634332893686268675876375].
Fibonacci, iterative version:
?- time(run(" \
\
(defun fib (n) \
(setq f (cons 0 1)) \
(setq i 0) \
(while (< i n) \
(setq f (cons (cdr f) (+ (car f) (cdr f)))) \
(setq i (+ i 1))) \
(car f)) \
\
(fib 350) \
\
", Vs)).% CPU time: 0.021s
Vs = [fib,6254449428820551641549772190170184190608177514674331726439961915653414425].
Higher-order programming and eval:
?- run(" \
\
(defun map (f xs) \
(if xs \
(cons (eval (list f (car xs))) (map f (cdr xs))) \
())) \
\
(defun plus1 (x) (+ 1 x)) \
\
(map 'plus1 '(1 2 3)) \
\
", Vs).
Vs = [map,plus1,[2,3,4]].More information about this interpreter is available at:
[**https://www.metalevel.at/lisprolog/**](https://www.metalevel.at/lisprolog/)