holy shit it works
This commit is contained in:
parent
1055ba154d
commit
d071fa74c5
2 changed files with 61 additions and 32 deletions
80
lambda.ml
80
lambda.ml
|
@ -5,7 +5,12 @@ open Types
|
||||||
|
|
||||||
exception EvaluationComplete
|
exception EvaluationComplete
|
||||||
|
|
||||||
let rec string_of_term (t:term) =
|
(*
|
||||||
|
((\a.(\b.((a a) b))) (\a.(\b.a))) (\a.(\b.a))
|
||||||
|
((\a.(\b.((a b) a))) (\a.(\b.a))) (\a.(\b.b))
|
||||||
|
*)
|
||||||
|
|
||||||
|
let rec string_of_term (t: Types.term) =
|
||||||
match t with
|
match t with
|
||||||
| TmAbs(x, t1) ->
|
| TmAbs(x, t1) ->
|
||||||
"(\\" ^ x ^ "." ^ (string_of_term t1) ^ ")"
|
"(\\" ^ x ^ "." ^ (string_of_term t1) ^ ")"
|
||||||
|
@ -13,40 +18,63 @@ let rec string_of_term (t:term) =
|
||||||
"(" ^ (string_of_term t1) ^ " " ^ (string_of_term t2) ^ ")"
|
"(" ^ (string_of_term t1) ^ " " ^ (string_of_term t2) ^ ")"
|
||||||
| TmVar(x) -> x
|
| TmVar(x) -> x
|
||||||
|
|
||||||
(*
|
let rec string_of_ctx (c: Types.context) =
|
||||||
let termshift d t =
|
match c with
|
||||||
let rec walk c t =
|
| [] -> ""
|
||||||
match t with
|
| (n, t)::r -> (n ^ ": " ^ (string_of_term t) ^ "\n" ^ (string_of_ctx r))
|
||||||
| TmVar(x) -> if
|
|
||||||
|
|
||||||
let termsubsttop (s:term) (t:term) =
|
let assign ctx (name, t) : Types.context =
|
||||||
termshift (-1) (termsubst 0 (termshift 1 s) t)
|
|
||||||
|
|
||||||
let rec isval ctx t =
|
|
||||||
match t with
|
|
||||||
| TmAbs(_, _, _) -> true
|
|
||||||
| _ -> false
|
|
||||||
|
|
||||||
let rec helper ctx t =
|
|
||||||
match t with
|
|
||||||
| TmApp(TmAbs(x, t1), v2) when isval ctx v2 -> termsubsttop v2 t1
|
|
||||||
| _ -> EvaluationComplete
|
|
||||||
*)
|
|
||||||
|
|
||||||
let assign ctx (name, t) : context =
|
|
||||||
(name, t)::ctx
|
(name, t)::ctx
|
||||||
|
|
||||||
let rec lookup ctx name : term =
|
let remove ctx name =
|
||||||
|
List.filter (fun (a, b) -> a != name) ctx
|
||||||
|
|
||||||
|
let rec lookup ctx name : Types.term =
|
||||||
match ctx with
|
match ctx with
|
||||||
| [] -> raise (Failure ("unbound variable " ^ name))
|
| [] -> print_endline ("unbound variable " ^ name); raise (Failure ("unbound variable " ^ name))
|
||||||
| (n, t)::tail ->
|
| (n, t)::tail ->
|
||||||
if n = name then t else lookup tail name
|
if n = name then t else lookup tail name
|
||||||
|
|
||||||
|
let rec subst name tm repl =
|
||||||
|
match tm with
|
||||||
|
| TmVar(x) -> if x = name then repl else TmVar(x)
|
||||||
|
| TmAbs(n, t) -> if n = name then TmAbs(n, t) else TmAbs(n, subst name t repl)
|
||||||
|
| TmApp(a, b) -> TmApp(subst name a repl, subst name b repl)
|
||||||
|
|
||||||
|
let rec try_subst name tm repl =
|
||||||
|
match tm with
|
||||||
|
| TmVar(x) -> if x = name then (true, repl) else (false, TmVar(x))
|
||||||
|
| TmAbs(n, t) -> if n = name then (false, TmAbs(n, t)) else (let (s, t') = try_subst name t repl in (s, TmAbs(n, t')))
|
||||||
|
| TmApp(a, b) -> (let ((sa, a'), (sb, b')) = (try_subst name a repl, try_subst name b repl) in (sa || sb, TmApp(a', b')))
|
||||||
|
|
||||||
let rec eval (ctx, t) =
|
let rec eval (ctx, t) =
|
||||||
let rec helper (ctx, t) =
|
let rec helper (ctx, t) d =
|
||||||
raise EvaluationComplete
|
(*print_endline ((String.init (d * 2) (fun _ -> ' ')) ^ "helper" ^ (string_of_term t));
|
||||||
|
print_endline (string_of_ctx ctx);*)
|
||||||
|
match t with
|
||||||
|
| TmApp(TmApp(_, _) as a, b) ->
|
||||||
|
let (_, a') = helper (ctx, a) (d + 1) in
|
||||||
|
helper (ctx, TmApp(a', b)) (d + 1)
|
||||||
|
| TmApp(TmAbs(n, t), r) ->
|
||||||
|
(* let ctx' = assign ctx (n, r) in
|
||||||
|
helper (ctx', t) (d + 1) *)
|
||||||
|
let (s, t') = try_subst n t r in
|
||||||
|
(*print_endline ("try_subst('" ^ n ^ "', " ^ (string_of_term t) ^ ", " ^ (string_of_term r) ^ ") = " ^ (if s then "true" else "false"));*)
|
||||||
|
if s then helper (ctx, t') (d + 1) else (ctx, t')
|
||||||
|
| TmApp(TmVar(n), b) ->
|
||||||
|
let (_, a) = helper (ctx, lookup ctx n) (d + 1) in
|
||||||
|
helper (ctx, TmApp(a, b)) (d + 1)
|
||||||
|
| TmVar(n) -> (ctx, lookup ctx n)
|
||||||
|
| TmAbs(_, TmVar(_)) as t -> (ctx, t)
|
||||||
|
| TmAbs(n, _) as t ->
|
||||||
|
let r = TmVar(n) in
|
||||||
|
let (s, t') = try_subst n t r in
|
||||||
|
(*print_endline ("try_subst('" ^ n ^ "', " ^ (string_of_term t) ^ ", " ^ (string_of_term r) ^ ") = " ^ (if s then "true" else "false"));*)
|
||||||
|
if s then helper (ctx, t') (d + 1) else (ctx, t')
|
||||||
|
| _ -> (*print_endline "called EvaluationComplete"; *)raise EvaluationComplete
|
||||||
in try
|
in try
|
||||||
let (ctx', t') = helper (ctx, t) in
|
let (ctx', t') = helper (ctx, t) 0 in
|
||||||
|
if t = t' then raise EvaluationComplete else
|
||||||
eval (ctx', t')
|
eval (ctx', t')
|
||||||
with EvaluationComplete -> (ctx, t)
|
with EvaluationComplete -> (ctx, t)
|
||||||
|
|
||||||
|
|
13
parser.mly
13
parser.mly
|
@ -10,8 +10,12 @@
|
||||||
%token <string> Ident
|
%token <string> Ident
|
||||||
%token Lambda
|
%token Lambda
|
||||||
|
|
||||||
|
%right prec_Abs
|
||||||
|
%left prec_App
|
||||||
|
|
||||||
%start main
|
%start main
|
||||||
%type <Types.input> main
|
%type <Types.input> main
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
main:
|
main:
|
||||||
|
@ -22,12 +26,9 @@ assign:
|
||||||
| Ident Equal expr { Types.Assign($1, $3) }
|
| Ident Equal expr { Types.Assign($1, $3) }
|
||||||
;
|
;
|
||||||
expr:
|
expr:
|
||||||
| var { Types.TmVar($1) }
|
| Ident { Types.TmVar($1) }
|
||||||
| LParen expr RParen { $2 }
|
| LParen expr RParen { $2 }
|
||||||
| Lambda var Dot expr { Types.TmAbs($2, $4) }
|
| Lambda Ident Dot expr %prec prec_Abs { Types.TmAbs($2, $4) }
|
||||||
| expr expr { Types.TmApp($1, $2) }
|
| expr expr %prec prec_App { Types.TmApp($1, $2) }
|
||||||
;
|
|
||||||
var:
|
|
||||||
Ident { $1 }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue