Skip to content

Instantly share code, notes, and snippets.

@webyrd
Created February 12, 2015 09:07
Show Gist options
  • Save webyrd/cd17429605ad9783587c to your computer and use it in GitHub Desktop.
Save webyrd/cd17429605ad9783587c to your computer and use it in GitHub Desktop.
;; relational scheme interpreter
;; (currently without absento)
(define lookupo
(lambda (x env out)
(fresh (y val env^)
(== `((,y . ,val) . ,env^) env)
(symbolo x)
(symbolo y)
(conde
((== x y) (== val out))
((=/= x y) (lookupo x env^ out))))))
(define unboundo
(lambda (x env)
(fresh ()
(symbolo x)
(conde
((== '() env))
((fresh (y v env^)
(== `((,y . ,v) . ,env^) env)
(=/= x y)
(unboundo x env^)))))))
(define eval-expo
(lambda (expr env out)
(fresh ()
(conde
((symbolo expr) ;; variable
(lookupo expr env out))
((== `(quote ,out) expr) ;; should have an (absento 'closure out)
(unboundo 'quote env))
((fresh (x body) ;; abstraction
(== `(lambda (,x) ,body) expr)
(== `(closure ,x ,body ,env) out)
(symbolo x)
(unboundo 'lambda env)))
((fresh (expr*)
(== `(list . ,expr*) expr)
(unboundo 'list env)
(eval-exp*o expr* env out)))
((fresh (e1 e2 val x body env^) ;; application
(== `(,e1 ,e2) expr)
(eval-expo e1 env `(closure ,x ,body ,env^))
(eval-expo e2 env val)
(eval-expo body `((,x . ,val) . ,env^) out)))))))
(define eval-exp*o
(lambda (expr* env out)
(conde
((== '() expr*) (== '() out))
((fresh (a d res-a res-d)
(== (cons a d) expr*)
(== (cons res-a res-d) out)
(eval-expo a env res-a)
(eval-exp*o d env res-d))))))
(eval-expo q '() q)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment