2024-04-30 11:44:28 +02:00
open Parser_entry
2024-04-09 11:30:52 +02:00
open Affichage
2024-04-16 10:07:09 +02:00
open Typing
2024-04-30 11:44:28 +02:00
open Proof
open Types
2024-04-09 11:09:33 +02:00
2024-04-16 11:40:08 +02:00
type entry =
Simple of Lam . lam
2024-04-25 04:20:12 +02:00
| Reduce of Lam . lam
2024-04-16 11:40:08 +02:00
| AlphaEquiv of Lam . lam * Lam . lam
2024-04-30 11:44:28 +02:00
let parse_lam t =
match Parser . main Lexer . token t with
| Lam l -> l
| Cmd _ -> failwith " entry must be a lam "
let parse_cmd t =
match Parser . main Lexer . token t with
| Cmd c -> c
| Lam _ -> failwith " entry must be a cmd "
2024-04-25 04:20:12 +02:00
let beta_reduce e =
let rec aux = function
Some e ->
print_expr e ;
print_newline () ;
aux ( Lam . betastep e ) ;
| None -> ()
in print_expr e ;
print_newline () ;
2024-04-25 04:33:42 +02:00
let e = Lam . alpha_convert ~ readable : true e in
2024-04-25 04:20:12 +02:00
print_expr e ;
print_newline () ;
aux ( Lam . betastep e )
let alpha_get_lam where_from =
let input_str = In_channel . input_all where_from in
match Str . split ( Str . regexp " & " ) input_str with
[ s1 ; s2 ] -> AlphaEquiv (
2024-04-30 11:44:28 +02:00
parse_lam ( Lexing . from_string ( s1 ^ " \n " ) ) ,
parse_lam ( Lexing . from_string s2 )
2024-04-25 04:20:12 +02:00
)
| _ -> failwith " Alpha-equivalence: nombre de delimiteurs incorrect "
2024-04-30 11:44:28 +02:00
let rec interactive ( ( g , gs ) : proof ) : proof =
begin
let fresh_proof ( ty : ty ) =
( Some ( Ref ( ref Hole ) , ty , [] ) , [] )
in
let _ = match g with
2024-05-01 11:07:40 +02:00
None -> print_string " \n \027 [1mNo more goals. \027 [0m \n "
2024-05-01 10:44:36 +02:00
| Some g' -> print_newline () ; print_goal g'
2024-04-30 11:44:28 +02:00
in
2024-05-01 10:35:12 +02:00
try
match parse_cmd ( Lexing . from_string ( ( read_line () ) ^ " \n " ) ) with
Goal ty -> fresh_proof ty | > interactive
2024-05-01 10:44:36 +02:00
| Tact t -> apply_tactic ( g , gs ) t | > interactive
2024-05-01 10:35:12 +02:00
with
Parser . Error ->
2024-05-01 11:07:40 +02:00
print_error " Invalid input " " " ;
2024-05-01 10:35:12 +02:00
interactive ( g , gs )
| End_of_file ->
print_string " Bye! \n " ;
( g , gs )
2024-05-01 11:07:40 +02:00
| TacticFailed arg ->
print_error " Tactic failed " arg ;
2024-05-01 10:44:36 +02:00
interactive ( g , gs )
2024-04-30 11:44:28 +02:00
end
2024-04-09 11:09:33 +02:00
let interpret e =
begin
2024-04-09 11:30:52 +02:00
print_expr e ;
2024-04-09 11:09:33 +02:00
print_newline () ;
2024-04-16 10:07:09 +02:00
print_ty ( typeinfer [] e ) ;
2024-04-30 11:44:28 +02:00
print_newline () ;
let _ = interactive ( None , [] ) in ()
2024-04-09 11:09:33 +02:00
end
2024-04-16 11:40:08 +02:00
let nom_fichier = ref " "
2024-04-25 04:20:12 +02:00
let reduce = ref false
2024-04-16 14:24:06 +02:00
let alpha = ref false
2024-04-25 04:20:12 +02:00
let equiv_fichier = ref " "
2024-04-16 11:40:08 +02:00
2024-04-30 11:44:28 +02:00
let parse_channel_lam c =
2024-04-16 11:40:08 +02:00
let lexbuf = Lexing . from_channel c in
2024-04-30 11:44:28 +02:00
parse_lam lexbuf
2024-04-16 11:40:08 +02:00
let recupere_entree () =
let optlist = [
2024-04-25 04:20:12 +02:00
( " -alpha " ,
Arg . Set alpha ,
" Vérifie l'alpha équivalence de deux termes séparés par & " ) ;
( " -reduce " ,
Arg . Set reduce ,
" Affiche les réductions successives du lambda-terme " )
2024-04-16 11:40:08 +02:00
] in
let usage = " Bienvenue à bord. " in (* message d'accueil, option -help *)
Arg . parse (* ci-dessous les 3 arguments de Arg.parse : *)
optlist (* la liste des options definie plus haut *)
( fun s -> nom_fichier := s ) (* la fonction a declencher lorsqu'on recupere un string qui n'est pas une option : ici c'est le nom du fichier, et on stocke cette information dans la reference nom_fichier *)
usage ; (* le message d'accueil *)
2024-04-16 14:24:06 +02:00
try
2024-04-16 11:40:08 +02:00
let where_from = match ! nom_fichier with
| " " -> stdin
| s -> open_in s in
2024-04-25 04:20:12 +02:00
if ! alpha
then alpha_get_lam where_from
else if ! reduce
2024-04-30 11:44:28 +02:00
then Reduce ( parse_channel_lam where_from )
else Simple ( parse_channel_lam where_from )
2024-05-01 11:07:40 +02:00
with e -> ( print_error " problème de saisie " " " ; raise e )
2024-04-09 11:09:33 +02:00
2024-04-16 11:40:08 +02:00
(* la fonction principale *)
let run () =
try
match recupere_entree () with
Simple l -> let _ = interpret l in ()
2024-04-25 04:20:12 +02:00
| Reduce l -> let _ = beta_reduce l in ()
2024-04-16 11:40:08 +02:00
| AlphaEquiv ( l1 , l2 ) -> begin
if ( ( Lam . ( = ~ ) ) l1 l2 ) then
print_string " true \n "
else
print_string " false \n "
end ;
flush stdout
with e -> raise e
2024-04-09 11:09:33 +02:00
2024-04-16 11:40:08 +02:00
let _ = run ()
2024-04-09 11:09:33 +02:00