demos:
saved files:
create file
save file
create link
relational interpreter
;; relational scheme interpreter (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) (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))) ((fresh (e1 e2 v1 v2) (== `(cons ,e1 ,e2) expr) (== `(,v1 . ,v2) out) (unboundo 'cons env) (eval-expo e1 env v1) (eval-expo e2 env v2))) ((fresh (e v2) (== `(car ,e) expr) (unboundo 'car env) (eval-expo e env `(,out . ,v2)))) ((fresh (e v1) (== `(cdr ,e) expr) (unboundo 'cdr env) (eval-expo e env `(,v1 . ,out)))) ((fresh (e v) (== `(null? ,e) expr) (conde ((== '() v) (== #t out)) ((=/= '() v) (== #f out))) (unboundo 'null? env) (eval-expo e env v))) ((fresh (t c a b) (== `(if ,t ,c ,a) expr) (unboundo 'if env) (eval-expo t env b) (conde ((== #f b) (eval-expo a env out)) ((=/= #f b) (eval-expo c 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)))))) ;; running append in reverse (eval-expo `((((lambda (f) ((lambda (x) (f (x x))) (lambda (x) (lambda (y) ((f (x x)) y))))) (lambda (my-append) (lambda (l) (lambda (s) (if (null? l) s (cons (car l) ((my-append (cdr l)) s))))))) (quote ,x)) (quote ,y)) '() '(a b c d e))
type inference
(define (!-o gamma expr type) (conde ((symbolo expr) (lookupo gamma expr type)) ((numbero expr) (== 'int type)) ((== #f expr) (== 'bool type)) ((== #t expr) (== 'bool type)) ((fresh (x e T1 T2) (== `(lambda (,x) ,e) expr) (== `(,T1 -> ,T2) type) (symbolo x) (!-o `((,x : ,T1) . ,gamma) e T2))) ((fresh (f e e^ t-ignore) (== `(let ((,f ,e)) ,e^) expr) (symbolo f) (!-o `((,f poly ,e ,gamma) . ,gamma) e^ type) (!-o gamma e t-ignore))) ((fresh (e1 e2 T) (== `(,e1 ,e2) expr) (!-o gamma e1 `(,T -> ,type)) (!-o gamma e2 T))) ((fresh (e1 e2) (== `(+ ,e1 ,e2) expr) (== 'int type) (!-o gamma e1 'int) (!-o gamma e2 'int))) ((fresh (e1 e2 T1 T2) (== `(cons ,e1 ,e2) expr) (== `(pair ,T1 ,T2) type) (!-o gamma e1 T1) (!-o gamma e2 T2))) ((fresh (e1 e2 e3) (== `(if ,e1 ,e2 ,e3) expr) (!-o gamma e1 'bool) (!-o gamma e2 type) (!-o gamma e3 type))))) (define (lookupo gamma x t) (fresh () (symbolo x) (conde ((fresh (e gamma^ _) (== `((,x poly ,e ,gamma^) . ,_) gamma) (!-o gamma^ e t))) ((fresh (_) (== `((,x : ,t) . ,_) gamma))) ((fresh (y _ gamma^) (== `((,y . ,_) . ,gamma^) gamma) (=/= x y) (symbolo y) (lookupo gamma^ x t)))))) (!-o '() '(let ((f (lambda (x) x))) (f (cons (f 5) (f #t)))) q)
numbers
;; number relations based on "oleg numbers" (define (appendo x y z) (conde ((== x '()) (== y z)) ((fresh (head xtail ytail ztail) (== x `(,head . ,xtail)) (== z `(,head . ,ztail)) (appendo xtail y ztail))))) (define zeroo (lambda (n) (== '() n))) (define poso (lambda (n) (fresh (a d) (== `(,a . ,d) n)))) (define >1o (lambda (n) (fresh (a ad dd) (== `(,a ,ad . ,dd) n)))) (define full-addero (lambda (b x y r c) (conde ((== 0 b) (== 0 x) (== 0 y) (== 0 r) (== 0 c)) ((== 1 b) (== 0 x) (== 0 y) (== 1 r) (== 0 c)) ((== 0 b) (== 1 x) (== 0 y) (== 1 r) (== 0 c)) ((== 1 b) (== 1 x) (== 0 y) (== 0 r) (== 1 c)) ((== 0 b) (== 0 x) (== 1 y) (== 1 r) (== 0 c)) ((== 1 b) (== 0 x) (== 1 y) (== 0 r) (== 1 c)) ((== 0 b) (== 1 x) (== 1 y) (== 0 r) (== 1 c)) ((== 1 b) (== 1 x) (== 1 y) (== 1 r) (== 1 c))))) (define addero (lambda (d n m r) (conde ((== 0 d) (== '() m) (== n r)) ((== 0 d) (== '() n) (== m r) (poso m)) ((== 1 d) (== '() m) (addero 0 n '(1) r)) ((== 1 d) (== '() n) (poso m) (addero 0 '(1) m r)) ((== '(1) n) (== '(1) m) (fresh (a c) (== `(,a ,c) r) (full-addero d 1 1 a c))) ((== '(1) n) (gen-addero d n m r)) ((== '(1) m) (>1o n) (>1o r) (addero d '(1) n r)) ((>1o n) (gen-addero d n m r))))) (define gen-addero (lambda (d n m r) (fresh (a b c e x y z) (== `(,a . ,x) n) (== `(,b . ,y) m) (poso y) (== `(,c . ,z) r) (poso z) (full-addero d a b c e) (addero e x y z)))) (define pluso (lambda (n m k) (addero 0 n m k))) (define minuso (lambda (n m k) (pluso m k n))) (define *o (lambda (n m p) (conde ((== '() n) (== '() p)) ((poso n) (== '() m) (== '() p)) ((== '(1) n) (poso m) (== m p)) ((>1o n) (== '(1) m) (== n p)) ((fresh (x z) (== `(0 . ,x) n) (poso x) (== `(0 . ,z) p) (poso z) (>1o m) (*o x m z))) ((fresh (x y) (== `(1 . ,x) n) (poso x) (== `(0 . ,y) m) (poso y) (*o m n p))) ((fresh (x y) (== `(1 . ,x) n) (poso x) (== `(1 . ,y) m) (poso y) (odd-*o x n m p)))))) (define odd-*o (lambda (x n m p) (fresh (q) (bound-*o q p n m) (*o x m q) (pluso `(0 . ,q) m p)))) (define bound-*o (lambda (q p n m) (conde ((== '() q) (poso p)) ((fresh (a0 a1 a2 a3 x y z) (== `(,a0 . ,x) q) (== `(,a1 . ,y) p) (conde ((== '() n) (== `(,a2 . ,z) m) (bound-*o x y z '())) ((== `(,a3 . ,z) n) (bound-*o x y z m)))))))) (define =lo (lambda (n m) (conde ((== '() n) (== '() m)) ((== '(1) n) (== '(1) m)) ((fresh (a x b y) (== `(,a . ,x) n) (poso x) (== `(,b . ,y) m) (poso y) (=lo x y)))))) (define
1o m)) ((fresh (a x b y) (== `(,a . ,x) n) (poso x) (== `(,b . ,y) m) (poso y) (
1o b) (=lo n b) (pluso r b n)) ((== '(1) b) (poso q) (pluso r '(1) n)) ((== '() b) (poso q) (== r n)) ((== '(0 1) b) (fresh (a ad dd) (poso dd) (== `(,a ,ad . ,dd) n) (exp2 n '() q) (fresh (s) (splito n dd r s)))) ((fresh (a ad add ddd) (conde ((== '(1 1) b)) ((== `(,a ,ad ,add . ,ddd) b)))) (
1o n) (== '(1) q) (fresh (s) (splito n b s '(1)))) ((fresh (q1 b2) (== `(0 . ,q1) q) (poso q1) (
1o q) (fresh (q1 nq1) (pluso q1 '(1) q) (repeated-mul n q1 nq1) (*o nq1 n nq)))))) (define expo (lambda (b q n) (logo n b q '()))) ;; factor the number 420 by running multiplication backwards! (*o x y '(0 0 1 0 0 1 0 1 1))
reasoned schemer prelude
(define caro (lambda (p a) (fresh (d) (== (cons a d) p)))) (define cdro (lambda (p d) (fresh (a) (== (cons a d) p)))) (define conso (lambda (a d p) (== (cons a d) p))) (define nullo (lambda (x) (== '() x))) (define eqo (lambda (x y) (== x y))) (define eq-caro (lambda (l x) (caro l x))) (define pairo (lambda (p) (fresh (a d) (conso a d p)))) (define listo (lambda (l) (conde ((nullo l)) ((pairo l) (fresh (d) (cdro l d) (listo d)))))) (define membero (lambda (x l) (conde ((eq-caro l x)) ((fresh (d) (cdro l d) (membero x d)))))) (define rembero (lambda (x l out) (conde ((nullo l) (== '() out)) ((eq-caro l x) (cdro l out)) ((fresh (a d res) (conso a d l) (rembero x d res) (conso a res out)))))) (define appendo (lambda (l s out) (conde ((nullo l) (== s out)) ((fresh (a d res) (conso a d l) (conso a res out) (appendo d s res)))))) (define anyo (lambda (g) (conde (g) ((anyo g))))) (define fail (== 'war 'peace)) (define succeed (== 'a 'a)) (define nevero (anyo fail)) (define alwayso (anyo succeed))
grammar
;; constructing sentences using relations (define (conso car cdr c) (== `(,car . ,cdr) c)) (define (membero x l) (fresh (head tail) (== l `(,head . ,tail)) (conde ((== x head)) ((membero x tail))))) (define (nouno n) (membero n '(cat bat))) (define (verbo v) (membero v '(eats))) (define (deto d) (membero d '(the a))) ;; fixed sentence structure (define (my-sentenceo s) (fresh (v n1 d1 n2 d2) (verbo v) (nouno n1) (nouno n2) (deto d1) (deto d2) (== s `(,d1 ,n1 ,v ,d2 ,n2)))) (my-sentenceo x) ;; with parameterized structure (define (wordo class word) (conde ((== class 'noun) (nouno word)) ((== class 'verb) (verbo word)) ((== class 'det) (deto word)))) (define (sentenceo grammar s) (conde ((== grammar '()) (== s '())) ((fresh (g-head s-head g-tail s-tail) (conso g-head g-tail grammar) (conso s-head s-tail s) (wordo g-head s-head) (sentenceo g-tail s-tail))))) (sentenceo '(det noun verb det noun) s)