Add Qed.
This commit is contained in:
parent
8569fe1ba2
commit
daa09cb58b
@ -32,6 +32,7 @@ rule token = parse
|
|||||||
|
|
||||||
| "Goal" { GOAL }
|
| "Goal" { GOAL }
|
||||||
| "Undo" { UNDO }
|
| "Undo" { UNDO }
|
||||||
|
| "Qed" { QED }
|
||||||
| "exact" { EXACT }
|
| "exact" { EXACT }
|
||||||
| "assumption" { ASSUMPTION }
|
| "assumption" { ASSUMPTION }
|
||||||
| "intros" { INTROS }
|
| "intros" { INTROS }
|
||||||
|
57
main.ml
57
main.ml
@ -9,6 +9,7 @@ type entry =
|
|||||||
| Reduce of Lam.lam
|
| Reduce of Lam.lam
|
||||||
| AlphaEquiv of Lam.lam * Lam.lam
|
| AlphaEquiv of Lam.lam * Lam.lam
|
||||||
|
|
||||||
|
type interactive_state = (hlam * ty) option * proof
|
||||||
|
|
||||||
let parse_lam t =
|
let parse_lam t =
|
||||||
match Parser.main Lexer.token t with
|
match Parser.main Lexer.token t with
|
||||||
@ -20,7 +21,7 @@ let parse_cmd t =
|
|||||||
| Cmd c -> c
|
| Cmd c -> c
|
||||||
| Lam _ -> failwith "entry must be a cmd"
|
| Lam _ -> failwith "entry must be a cmd"
|
||||||
|
|
||||||
let beta_reduce e =
|
let show_beta_reduction e =
|
||||||
let rec aux = function
|
let rec aux = function
|
||||||
Some e ->
|
Some e ->
|
||||||
print_expr e;
|
print_expr e;
|
||||||
@ -34,6 +35,17 @@ let beta_reduce e =
|
|||||||
print_newline ();
|
print_newline ();
|
||||||
aux (Lam.betastep e)
|
aux (Lam.betastep e)
|
||||||
|
|
||||||
|
let rec beta_reduce (l : Lam.lam) =
|
||||||
|
match Lam.betastep l with
|
||||||
|
| None -> l
|
||||||
|
| Some l' -> beta_reduce l'
|
||||||
|
|
||||||
|
let clean_state ((s, p) : interactive_state) =
|
||||||
|
let assoc, new_p = clean_proof p in
|
||||||
|
match s with
|
||||||
|
| None -> None, new_p
|
||||||
|
| Some (hl, ty) -> Some (clean_hlam assoc hl, ty), new_p
|
||||||
|
|
||||||
let alpha_get_lam where_from =
|
let alpha_get_lam where_from =
|
||||||
let input_str = In_channel.input_all where_from in
|
let input_str = In_channel.input_all where_from in
|
||||||
match Str.split (Str.regexp "&") input_str with
|
match Str.split (Str.regexp "&") input_str with
|
||||||
@ -43,12 +55,13 @@ let alpha_get_lam where_from =
|
|||||||
)
|
)
|
||||||
| _ -> failwith "Alpha-equivalence: nombre de delimiteurs incorrect"
|
| _ -> failwith "Alpha-equivalence: nombre de delimiteurs incorrect"
|
||||||
|
|
||||||
let rec interactive ((g, gs)::gq : proof list) : proof =
|
(** Interactive loop
|
||||||
|
- cg : current top goal : type and reference to lambda-term
|
||||||
|
- g, gs : next goals
|
||||||
|
- sq : previous states of the interactive loop
|
||||||
|
*)
|
||||||
|
let rec interactive ((cg, (g, gs))::sq : (interactive_state) list) : proof =
|
||||||
begin
|
begin
|
||||||
let fresh_proof (ty : ty) =
|
|
||||||
(Some (Ref (ref Hole), ty, []), [])
|
|
||||||
in
|
|
||||||
|
|
||||||
let _ = match g with
|
let _ = match g with
|
||||||
None -> print_string "\n\027[1mNo more goals.\027[0m\n"
|
None -> print_string "\n\027[1mNo more goals.\027[0m\n"
|
||||||
| Some g' -> print_newline (); print_goal g'
|
| Some g' -> print_newline (); print_goal g'
|
||||||
@ -56,16 +69,34 @@ let rec interactive ((g, gs)::gq : proof list) : proof =
|
|||||||
|
|
||||||
try
|
try
|
||||||
match parse_cmd (Lexing.from_string ((read_line ())^"\n")) with
|
match parse_cmd (Lexing.from_string ((read_line ())^"\n")) with
|
||||||
Goal ty -> [fresh_proof ty] |> interactive
|
Goal ty ->
|
||||||
| Undo -> interactive gq
|
let rh = Ref (ref Hole) in
|
||||||
| Tact t -> (apply_tactic (g, gs) t)::(clean_proof (g, gs))::gq |> interactive
|
interactive [Some (rh, ty), (Some (rh, ty, []), [])]
|
||||||
|
| Undo -> interactive sq
|
||||||
|
| Qed -> begin match cg with
|
||||||
|
None ->
|
||||||
|
print_error "No current goal" "";
|
||||||
|
(cg, (g, gs))::sq |> interactive
|
||||||
|
| Some (h, t) ->
|
||||||
|
let l = lam_of_hlam h
|
||||||
|
|> beta_reduce in
|
||||||
|
if Typing.typecheck [] l t then begin
|
||||||
|
print_string "Ok";
|
||||||
|
interactive [None, (None, [])]
|
||||||
|
end else begin
|
||||||
|
print_error "Typing failed" "";
|
||||||
|
(cg, (g, gs))::sq |> interactive
|
||||||
|
end
|
||||||
|
end
|
||||||
|
| Tact t ->
|
||||||
|
(cg, (apply_tactic (g, gs) t))::(clean_state (cg, (g, gs)))::sq |> interactive
|
||||||
with
|
with
|
||||||
Parser.Error ->
|
Parser.Error ->
|
||||||
print_error "Invalid input" "";
|
print_error "Invalid input" "";
|
||||||
(g, gs)::gq |> interactive
|
(cg, (g, gs))::sq |> interactive
|
||||||
| TacticFailed arg ->
|
| TacticFailed arg ->
|
||||||
print_error "Tactic failed" arg;
|
print_error "Tactic failed" arg;
|
||||||
(g, gs)::gq |> interactive
|
(cg, (g, gs))::sq |> interactive
|
||||||
| End_of_file ->
|
| End_of_file ->
|
||||||
print_string "Bye!\n";
|
print_string "Bye!\n";
|
||||||
(g, gs)
|
(g, gs)
|
||||||
@ -77,7 +108,7 @@ let interpret e =
|
|||||||
print_newline();
|
print_newline();
|
||||||
print_ty (typeinfer [] e);
|
print_ty (typeinfer [] e);
|
||||||
print_newline();
|
print_newline();
|
||||||
let _ = interactive [(None, [])] in ()
|
let _ = interactive [None, (None, [])] in ()
|
||||||
end
|
end
|
||||||
|
|
||||||
let nom_fichier = ref ""
|
let nom_fichier = ref ""
|
||||||
@ -123,7 +154,7 @@ let run () =
|
|||||||
try
|
try
|
||||||
match recupere_entree () with
|
match recupere_entree () with
|
||||||
Simple l -> let _ = interpret l in ()
|
Simple l -> let _ = interpret l in ()
|
||||||
| Reduce l -> let _ = beta_reduce l in ()
|
| Reduce l -> let _ = show_beta_reduction l in ()
|
||||||
| AlphaEquiv (l1, l2) -> begin
|
| AlphaEquiv (l1, l2) -> begin
|
||||||
if ((Lam.(=~)) l1 l2) then
|
if ((Lam.(=~)) l1 l2) then
|
||||||
print_string "true\n"
|
print_string "true\n"
|
||||||
|
@ -14,7 +14,8 @@ open Parser_entry
|
|||||||
%token <string> VARID
|
%token <string> VARID
|
||||||
%token <string> TYID
|
%token <string> TYID
|
||||||
|
|
||||||
%token GOAL UNDO EXACT ASSUMPTION INTRO INTROS CUT APPLY
|
%token GOAL UNDO QED
|
||||||
|
%token EXACT ASSUMPTION INTRO INTROS CUT APPLY
|
||||||
%token LEFT RIGHT SPLIT
|
%token LEFT RIGHT SPLIT
|
||||||
|
|
||||||
%token EOL
|
%token EOL
|
||||||
@ -37,6 +38,7 @@ tactic:
|
|||||||
command:
|
command:
|
||||||
| GOAL t=ty { Goal t }
|
| GOAL t=ty { Goal t }
|
||||||
| UNDO { Undo }
|
| UNDO { Undo }
|
||||||
|
| QED { Qed }
|
||||||
| EXACT e=expression { Tact (Exact_term e) }
|
| EXACT e=expression { Tact (Exact_term e) }
|
||||||
| EXACT s=TYID { Tact (Exact_proof s) }
|
| EXACT s=TYID { Tact (Exact_proof s) }
|
||||||
| ASSUMPTION { Tact (Assumption) }
|
| ASSUMPTION { Tact (Assumption) }
|
||||||
|
@ -5,6 +5,7 @@ open Proof
|
|||||||
type cmd =
|
type cmd =
|
||||||
| Goal of ty
|
| Goal of ty
|
||||||
| Undo
|
| Undo
|
||||||
|
| Qed
|
||||||
| Tact of tactic
|
| Tact of tactic
|
||||||
|
|
||||||
type parser_entry =
|
type parser_entry =
|
||||||
|
21
proof.ml
21
proof.ml
@ -36,9 +36,7 @@ let get_fresh_hyp () =
|
|||||||
(hyp_id, var_id)
|
(hyp_id, var_id)
|
||||||
|
|
||||||
(** replace ref's in a proof *)
|
(** replace ref's in a proof *)
|
||||||
let clean_proof ((g, gs) : proof) : proof =
|
let clean_hlam assoc (h : hlam) : hlam =
|
||||||
let assoc = ref [] in
|
|
||||||
let clean_hlam (h : hlam) : hlam =
|
|
||||||
let rec clean (h : hlam) : hlam= match h with
|
let rec clean (h : hlam) : hlam= match h with
|
||||||
HFun ((s, t), h) -> HFun ((s, t), clean h)
|
HFun ((s, t), h) -> HFun ((s, t), clean h)
|
||||||
| Hole -> Hole
|
| Hole -> Hole
|
||||||
@ -52,18 +50,17 @@ let clean_proof ((g, gs) : proof) : proof =
|
|||||||
Ref new_h)
|
Ref new_h)
|
||||||
| Some new_h -> Ref new_h
|
| Some new_h -> Ref new_h
|
||||||
in clean h
|
in clean h
|
||||||
in
|
let rec clean_context assoc (c : context) : context = match c with
|
||||||
let rec clean_context (c : context) : context = match c with
|
|
||||||
[] -> []
|
[] -> []
|
||||||
| (s1, s2, h, t)::q -> (s1, s2, clean_hlam h, t)::(clean_context q)
|
| (s1, s2, h, t)::q -> (s1, s2, clean_hlam assoc h, t)::(clean_context assoc q)
|
||||||
in
|
let clean_goal assoc ((h, t, c) : goal) : goal =
|
||||||
let clean_goal ((h, t, c) : goal) : goal =
|
(clean_hlam assoc h, t, clean_context assoc c)
|
||||||
(clean_hlam h, t, clean_context c)
|
let clean_proof ((g, gs) : proof) : (hlam ref * hlam ref) list ref * proof =
|
||||||
in
|
let assoc = ref [] in
|
||||||
let g' = match g with
|
let g' = match g with
|
||||||
| Some g -> Some (clean_goal g)
|
| Some g -> Some (clean_goal assoc g)
|
||||||
| None -> None
|
| None -> None
|
||||||
in (g', List.map clean_goal gs)
|
in assoc, (g', List.map (clean_goal assoc) gs)
|
||||||
|
|
||||||
let goal_is_over ((g, _) : proof) : bool =
|
let goal_is_over ((g, _) : proof) : bool =
|
||||||
match g with
|
match g with
|
||||||
|
Loading…
Reference in New Issue
Block a user