Add Undo command

This commit is contained in:
augustin64 2024-05-11 11:44:43 +02:00
parent 5f28463a37
commit 8569fe1ba2
5 changed files with 46 additions and 12 deletions

View File

@ -31,6 +31,7 @@ rule token = parse
| "\\/" { OR } | "\\/" { OR }
| "Goal" { GOAL } | "Goal" { GOAL }
| "Undo" { UNDO }
| "exact" { EXACT } | "exact" { EXACT }
| "assumption" { ASSUMPTION } | "assumption" { ASSUMPTION }
| "intros" { INTROS } | "intros" { INTROS }

17
main.ml
View File

@ -43,7 +43,7 @@ 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) : proof) : proof = let rec interactive ((g, gs)::gq : proof list) : proof =
begin begin
let fresh_proof (ty : ty) = let fresh_proof (ty : ty) =
(Some (Ref (ref Hole), ty, []), []) (Some (Ref (ref Hole), ty, []), [])
@ -56,18 +56,19 @@ let rec interactive ((g, gs) : proof) : 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 -> [fresh_proof ty] |> interactive
| Tact t -> apply_tactic (g, gs) t |> interactive | Undo -> interactive gq
| Tact t -> (apply_tactic (g, gs) t)::(clean_proof (g, gs))::gq |> interactive
with with
Parser.Error -> Parser.Error ->
print_error "Invalid input" ""; print_error "Invalid input" "";
interactive (g, gs) (g, gs)::gq |> interactive
| TacticFailed arg ->
print_error "Tactic failed" arg;
(g, gs)::gq |> interactive
| End_of_file -> | End_of_file ->
print_string "Bye!\n"; print_string "Bye!\n";
(g, gs) (g, gs)
| TacticFailed arg ->
print_error "Tactic failed" arg;
interactive (g, gs)
end end
let interpret e = let interpret e =
@ -76,7 +77,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, [])] in ()
end end
let nom_fichier = ref "" let nom_fichier = ref ""

View File

@ -14,7 +14,7 @@ open Parser_entry
%token <string> VARID %token <string> VARID
%token <string> TYID %token <string> TYID
%token GOAL EXACT ASSUMPTION INTRO INTROS CUT APPLY %token GOAL UNDO EXACT ASSUMPTION INTRO INTROS CUT APPLY
%token LEFT RIGHT SPLIT %token LEFT RIGHT SPLIT
%token EOL %token EOL
@ -36,6 +36,7 @@ tactic:
command: command:
| GOAL t=ty { Goal t } | GOAL t=ty { Goal t }
| UNDO { Undo }
| 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) }

View File

@ -4,6 +4,7 @@ open Proof
type cmd = type cmd =
| Goal of ty | Goal of ty
| Undo
| Tact of tactic | Tact of tactic
type parser_entry = type parser_entry =

View File

@ -27,14 +27,44 @@ type tactic =
| Right | Right
| Left | Left
let count = ref 0 let hyp_count = ref 0
let get_fresh_hyp () = let get_fresh_hyp () =
let n = string_of_int !count in let n = string_of_int !hyp_count in
incr count; incr hyp_count;
let hyp_id = "H" ^ n in let hyp_id = "H" ^ n in
let var_id = "x_" ^ n in let var_id = "x_" ^ n in
(hyp_id, var_id) (hyp_id, var_id)
(** replace ref's in a proof *)
let clean_proof ((g, gs) : proof) : proof =
let assoc = ref [] in
let clean_hlam (h : hlam) : hlam =
let rec clean (h : hlam) : hlam= match h with
HFun ((s, t), h) -> HFun ((s, t), clean h)
| Hole -> Hole
| HApp (h1, h2) -> HApp (clean h1, clean h2)
| HVar s -> HVar s
| HExf (h, t) -> HExf (clean h, t)
| Ref (hr) ->
match List.assq_opt hr !assoc with
None -> let new_h = ref (clean !hr)
in (assoc := (hr, new_h)::!assoc;
Ref new_h)
| Some new_h -> Ref new_h
in clean h
in
let rec clean_context (c : context) : context = match c with
[] -> []
| (s1, s2, h, t)::q -> (s1, s2, clean_hlam h, t)::(clean_context q)
in
let clean_goal ((h, t, c) : goal) : goal =
(clean_hlam h, t, clean_context c)
in
let g' = match g with
| Some g -> Some (clean_goal g)
| None -> None
in (g', List.map clean_goal gs)
let goal_is_over ((g, _) : proof) : bool = let goal_is_over ((g, _) : proof) : bool =
match g with match g with
None -> true None -> true