Created
July 20, 2018 22:07
-
-
Save hsk/2ee5b8acb62a20649cb276b256229997 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% Dervation System EvalContML4 | |
:- module('EvalContML4',[ | |
op(640,xfy,[$,$>]), | |
op(700,xfy,=>), | |
op(750,xfx,⇓), | |
op(780,xfx,⊦), | |
op(1200,xfx,--), | |
v/1,k/1,e/1,'⊦'/2,'⇓'/2 | |
]). | |
:- use_module(rtg). | |
term_expansion(A--B,B:-A). | |
% Syntax | |
syntax(integer). syntax(ε). syntax(k). syntax(maplist(_)). | |
int ::= integer. bool ::= true | false. | |
x ::= atom. | |
i ::= int. | |
b ::= bool. | |
e ::= i | b | x | e + e | e - e | e * e | e < e | if(e,e,e) | |
| let(x=e ;e) | fun(x->e) | e $ e | letrec(x=(x->e); e) | |
| [] | [e | e] | e$>{[]->e | [x|x]->e} | |
| letcc(x; e) | {k}. | |
v ::= i | b | fun(ε,x->e) | rec(ε,x=(x->e)) | [] | [v|v] | {k}. | |
ε ::= [] | [x=v|ε]. | |
op::= (+) | (-) | (*) | (<). | |
k1::= (ε⊦if(o,e,e)) | |
| ε⊦o+e | ε⊦o-e | ε⊦o*e | ε⊦o<e | |
| v+o | v-o | v*o | v<o | |
| ε⊦let(x=o;e) | |
| ε⊦o$e | |
| v$o | |
| ε⊦[o|e] | |
| [v|o] | |
| ε⊦o$>{[]->e|[x|x]->e}. | |
k ::= maplist(k1). | |
% Derivation Rules: | |
_⊦[E|K] ⇓ _ :- writeln([E|K]),fail. % (E-Log) | |
_⊦[V|K] ⇓ V2 :- v(V),V => K ⇓ V2. % (E-V) | |
ℰ⊦[if(E1,E2,E3)|K]⇓V :- ℰ⊦[E1,(ℰ⊦if(o,E2,E3))|K] ⇓ V. % (E-If) | |
ℰ⊦[E|K] ⇓ V :- E =..[Op,E1,E2],op(Op),E_ =..[Op,o,E2], | |
ℰ⊦[E1,(ℰ⊦ E_)|K] ⇓ V. % (E-BinOp) | |
ℰ⊦[X|K] ⇓ V2 :- member(X=V1,ℰ),V1 => K ⇓ V2. % (E-Var) | |
ℰ⊦[let(X=E1;E2)|K]⇓V :- ℰ⊦[E1,(ℰ⊦ let(X=o; E2))|K] ⇓ V. % (E-Let) | |
ℰ⊦[fun(X->E)|K] ⇓ V :- fun(ℰ,X->E) =>K ⇓ V. % (E-Fun) | |
ℰ⊦[E1 $ E2|K] ⇓ V :- ℰ⊦[E1,(ℰ⊦o$ E2)|K] ⇓ V. % (E-App) | |
ℰ⊦[letrec(X=(Y->E1);E2)|K]⇓V | |
:- [X=rec(ℰ,X=(Y->E1))|ℰ]⊦[E2|K] ⇓ V. % (E-LetRec) | |
_⊦[[]|K] ⇓ V :- [] => K ⇓ V. % (E-Nil) | |
ℰ⊦[[E1|E2]|K] ⇓ V :- ℰ⊦[E1,(ℰ⊦[o|E2])|K] ⇓ V. % (E-Cons) | |
ℰ⊦[E$>{[]->E2|[X|Y]->E3}|K]⇓V | |
:- ℰ⊦[E,ℰ⊦o$>{[]->E2|[X|Y]->E3}|K]⇓V.% (E-Match) | |
ℰ⊦[letcc(X; E)|K]⇓V :- [X={K}|ℰ]⊦[E|K] ⇓ V. % (E-LetCc) | |
E => K ⇓ _ :- writeln(E => K),fail. % (C-Log) | |
V => [] ⇓ V :- v(V). % (C-Ret) | |
V1 => [ℰ⊦ E1|K] ⇓ V2 :- E1=..[Op,o,E],op(Op),E2=..[Op,V1,o], | |
v(V1),ℰ⊦[E,E2|K] ⇓ V2. % (C-EvalR) | |
I2 => [I1 + o|K] ⇓ V :- I3 is I1 + I2,I3 => K ⇓ V. % (C-Plus) | |
I2 => [I1 - o|K] ⇓ V :- I3 is I1 - I2,I3 => K ⇓ V. % (C-Minus) | |
I2 => [I1 * o|K] ⇓ V :- I3 is I1 * I2,I3 => K ⇓ V. % (C-Times) | |
I2 => [I1 < o|K] ⇓ V :- I1 < I2,true => K ⇓ V. % (C-Lt1) | |
I2 => [I1 < o|K] ⇓ V :- I1 >= I2,false => K ⇓ V. % (C-Lt2) | |
true=>[ℰ⊦if(o,E1,_)|K]⇓V :- ℰ⊦[E1|K] ⇓ V. % (C-IfT) | |
false=>[ℰ⊦if(o,_,E2)|K]⇓V :- ℰ⊦[E2|K] ⇓ V. % (C-IfF) | |
V1=>[ℰ⊦let(X=_;E)|K]⇓V2 :- v(V1),[X=V1|ℰ]⊦[E|K] ⇓ V2. % (C-LetBody) | |
V1=>[ℰ⊦o$E|K] ⇓ V :- v(V1),ℰ⊦[E,(V1 $ o)|K] ⇓ V. % (C-EvalArg) | |
V1=>[fun(ℰ,X->E)$o|K]⇓V2 :- [X=V1|ℰ]⊦[E|K] ⇓ V2. % (C-EvalFun) | |
V1=>[rec(ℰ,X=(Y->E))$o|K]⇓V:- [X=rec(ℰ,X=(Y->E)),Y=V1|ℰ]⊦[E|K]⇓V.% (C-EvalFunR) | |
V1=>[{K1}$o|_] ⇓ V2 :- V1=>K1 ⇓ V2. % (C-EvalFunC) | |
V1=>[ℰ⊦[o|E]|K] ⇓ V2 :- ℰ⊦[E,[V1|o]|K] ⇓ V2. % (C-EvalConsR) | |
V2=>[[V1|o]|K] ⇓ V3 :- [V1|V2]=>K ⇓ V3. % (C-Cons) | |
[]=>[ℰ⊦o$>{[]->E1|[_|_]->_}|K]⇓V :- ℰ⊦[E1|K]⇓V. % (C-MatchNil) | |
[V1|V2]=>[ℰ⊦o$>{[]->_|[X|Y]->E}|K]⇓V :- [X=V1,Y=V2|ℰ]⊦[E|K]⇓V. % (C-MatchCons) | |
run(E,EV) :- e(E),write(E),write(->),[]⊦[E] ⇓ V,writeln(V),!,V=EV. | |
:- begin_tests(run). | |
test(i) :- run(1,1). | |
test(b) :- run(true,true),run(false,false). | |
test(x) :- run(let(x=1;x),1),run(let(abc=2;abc),2),run(let('ZZZ'=3;'ZZZ'),3). | |
test(+) :- run(1+1,2). | |
test(-) :- run(2-2,0). | |
test(*) :- run(3*3,9). | |
test(<) :- run(4<4,false). | |
test(op):- run(1+2*3<1,false). | |
test(if) :- run(if(true,1,2),1). | |
test(if):- run(if(true,true,false),true). | |
test(if):- run(if(1+2*3<1,true,false),false). | |
test(let) :- run(let(z=1;z+1),2). | |
test(fun) :- run(fun(z->z+1),fun([],z->z+1)). | |
test(app) :- run(fun(z->z+1) $ 3,4). | |
test(letrec) :- run(letrec(f=(z->z+1); f $ 2),3). | |
test(list0) :- run([],[]). | |
test(pair) :- run([1 | 2],[1|2]). | |
test(list1) :- run([1],[1]). | |
test(list2) :- run([1,2],[1,2]). | |
test(match) :- run([]$>{[]->0 | [a|b]->a},0). | |
test(match) :- run([1|2]$>{[]->0 | [a|b]->a},1). | |
test(match) :- run([1|2]$>{[]->0 | [a|b]->a+b},3). | |
test(letcc) :- run(letcc(k; k),{[]}). | |
test(letcc) :- run(let(sm = fun(f -> (f $ 3) + (f $ 4)); letcc(k; (sm $ k))),3). | |
test(letcc) :- run(2+letcc(k; 3),5). | |
test(letcc) :- run(2+letcc(k; 1+(k $ 3)),5). | |
test(letcc) :- run(letcc(k; 1+if(true,k$[10],2)),_). | |
test(letcc) :- run(letcc(top;2+letcc(k;top $ k)),{[2 + o]}). | |
test(letcc) :- run({[2 + o]},{[2 + o]}). | |
test(letcc) :- run({[2 + o]}$3,5). | |
test(letcc) :- run(letcc(top;let(x=1;x+2+letcc(k;top $ k))),{[3+ o]}). | |
:- end_tests(run). | |
% :- run_tests. :- halt. | |
:- begin_tests(k). | |
test(if) :- k([[x=1,y=2]⊦if(o,x,y)]). | |
test(+) :- k([[x=1]⊦o+ x]). | |
test(-) :- k([[x=1]⊦o- x]). | |
test(*) :- k([[x=1]⊦o* x]). | |
test(<) :- k([[x=1]⊦o< x]). | |
test(+) :- k([3 + o]). | |
test(-) :- k([3 - o]). | |
test(*) :- k([3 * o]). | |
test(<) :- k([3 < o]). | |
test(let) :- k([[x=1]⊦ let(z=o; z+1)]). | |
test(app) :- k([[x=1]⊦ o $ x]). | |
test(app) :- k([1 $ o]). | |
test(pair) :- k([[x=1]⊦[o| 2]]). | |
test(list2) :- k([[2|o]]). | |
test(match) :- k([[x=1]⊦o$>{[]->0 | [a|b]->a}]). | |
:- end_tests(k). | |
:- begin_tests(e). | |
test(i) :- e(1). | |
test(b) :- e(true),e(false). | |
test(x) :- e(x),e(abc),e('ZZZ'). | |
test(+) :- e(1+1). | |
test(-) :- e(2-2). | |
test(*) :- e(3*3). | |
test(<) :- e(4<4). | |
test(if) :- e(if(true,1,2)). | |
test(let) :- e(let(z=1;z+1)). | |
test(fun) :- e(fun(z->z+1)). | |
test(app) :- e(fun(z->z+1) $ 3). | |
test(letrec) :- e(letrec(f=(z->z+1); f $ 2)). | |
test(list0) :- e([]). | |
test(pair) :- e([1 | 2]). | |
test(list1) :- e([1]). | |
test(list2) :- e([1,2]). | |
test(match) :- e([]$>{[]->0 | [a|b]->a}). | |
test(letcc) :- e(letcc(x; 1+2)). | |
:- end_tests(e). | |
:- begin_tests(syntax). | |
test(syntax) :- writeln(ε;((a⊦a),a)). | |
:- end_tests(syntax). | |
:- begin_tests(v). | |
test(i) :- v(1),v(true),v(false). | |
test(fun) :- v(fun([x=2],x->1)). | |
test(rec) :- v(rec([x=2],z=(y->1))). | |
test(list) :- v([]). | |
test(list) :- v([1]). | |
test(list) :- v([1,2]). | |
test(list) :- v([1|2]). | |
test(k) :- v({[]}). | |
test(k_if) :- v({[[x=1,y=2]⊦if(o,x,y)]}). | |
test('k +') :- v({[[x=1]⊦o+ x]}). | |
test('k -') :- v({[[x=1]⊦o- x]}). | |
test('k *') :- v({[[x=1]⊦o* x]}). | |
test('k <') :- v({[[x=1]⊦o< x]}). | |
test('k +') :- v({[3 + o]}). | |
test('k -') :- v({[3 - o]}). | |
test('k *') :- v({[3 * o]}). | |
test('k <') :- v({[3 < o]}). | |
test(k_let) :- v({[[x=1]⊦ let(z=o; z+1)]}). | |
test(k_app) :- v({[[x=1]⊦ o $ x]}). | |
test(k_app) :- v({[1 $ o]}). | |
test(k_pair) :- v({[[x=1]⊦[o| 2]]}). | |
test(k_list2) :- v({[[2|o]]}). | |
test(k_match) :- v({[[x=1]⊦o$>{[]->0 | [a|b]->a}]}). | |
:- end_tests(v). | |
:- run_tests. | |
:- halt. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment