(* #use "/cygdrive/D/Tools/coq-7avril/dev/base_include";; open Coqast;; *) open Environ open Evd open Names open Nameops open Libnames open Term open Termops open Util open Proof_type open Pfedit open Translate open Term open Reductionops open Clenv open Typing open Inductive open Inductiveops open Vernacinterp open Declarations open Showproof_ct open Proof_trees open Sign open Pp open Printer open Rawterm open Tacexpr open Genarg (*****************************************************************************) (* Arbre de preuve maison: *) (* hypotheses *) type nhyp = {hyp_name : identifier; hyp_type : Term.constr; hyp_full_type: Term.constr} ;; type ntactic = tactic_expr ;; type nproof = Notproved | Proof of ntactic * (ntree list) and ngoal= {newhyp : nhyp list; t_concl : Term.constr; t_full_concl: Term.constr; t_full_env: Environ.named_context_val} and ntree= {t_info:string; t_goal:ngoal; t_proof : nproof} ;; let hyps {t_info=info; t_goal={newhyp=lh;t_concl=g;t_full_concl=gf;t_full_env=ge}; t_proof=p} = lh ;; let concl {t_info=info; t_goal={newhyp=lh;t_concl=g;t_full_concl=gf;t_full_env=ge}; t_proof=p} = g ;; let proof {t_info=info; t_goal={newhyp=lh;t_concl=g;t_full_concl=gf;t_full_env=ge}; t_proof=p} = p ;; let g_env {t_info=info; t_goal={newhyp=lh;t_concl=g;t_full_concl=gf;t_full_env=ge}; t_proof=p} = ge ;; let sub_ntrees t = match (proof t) with Notproved -> [] | Proof (_,l) -> l ;; let tactic t = match (proof t) with Notproved -> failwith "no tactic applied" | Proof (t,_) -> t ;; (* un arbre est clos s'il ne contient pas de sous-but non prouves, ou bien s'il a un cousin gauche qui n'est pas clos ce qui fait qu'on a au plus un sous-but non clos, le premier sous-but. *) let update_closed nt = let found_not_closed=ref false in let rec update {t_info=b; t_goal=g; t_proof =p} = if !found_not_closed then {t_info="to_prove"; t_goal=g; t_proof =p} else match p with Notproved -> found_not_closed:=true; {t_info="not_proved"; t_goal=g; t_proof =p} | Proof(tac,lt) -> let lt1=List.map update lt in let b=ref "proved" in (List.iter (fun x -> if x.t_info ="not_proved" then b:="not_proved") lt1; {t_info=(!b); t_goal=g; t_proof=Proof(tac,lt1)}) in update nt ;; (* type complet avec les hypotheses. *) let long_type_hyp lh t= let t=ref t in List.iter (fun (n,th) -> let ni = match n with Name ni -> ni | _ -> assert false in t:= mkProd(n,th,subst_term (mkVar ni) !t)) (List.rev lh); !t ;; (* let long_type_hyp x y = y;; *) (* Expansion des tactikelles *) let seq_to_lnhyp sign sign' cl = let lh= ref (List.map (fun (x,c,t) -> (Name x, t)) sign) in let nh=List.map (fun (id,c,ty) -> {hyp_name=id; hyp_type=ty; hyp_full_type= let res= long_type_hyp !lh ty in lh:=(!lh)@[(Name id,ty)]; res}) sign' in {newhyp=nh; t_concl=cl; t_full_concl=long_type_hyp !lh cl; t_full_env = Environ.val_of_named_context (sign@sign')} ;; let rule_is_complex r = match r with Nested (Tactic ((TacArg (Tacexp _) |TacAtom (_,(TacAuto _|TacSymmetry _))),_),_) -> true |_ -> false ;; let rule_to_ntactic r = let rt = (match r with Nested(Tactic (t,_),_) -> t | Prim (Refine h) -> TacAtom (dummy_loc,TacExact (Tactics.inj_open h)) | _ -> TacAtom (dummy_loc, TacIntroPattern [])) in if rule_is_complex r then (match rt with TacArg (Tacexp _) as t -> t | _ -> assert false) else rt ;; (* Attribue les preuves de la liste l aux sous-buts non-prouvés de nt *) let fill_unproved nt l = let lnt = ref l in let rec fill nt = let {t_goal=g;t_proof=p}=nt in match p with Notproved -> let p=List.hd (!lnt) in lnt:=List.tl (!lnt); {t_info="to_prove";t_goal=g;t_proof=p} |Proof(tac,lt) -> {t_info="to_prove";t_goal=g; t_proof=Proof(tac,List.map fill lt)} in fill nt ;; (* Differences entre signatures *) let new_sign osign sign = let res=ref [] in List.iter (fun (id,c,ty) -> try (let (_,_,_ty1)= (lookup_named id osign) in ()) with Not_found -> res:=(id,c,ty)::(!res)) sign; !res ;; let old_sign osign sign = let res=ref [] in List.iter (fun (id,c,ty) -> try (let (_,_,ty1) = (lookup_named id osign) in if ty1 = ty then res:=(id,c,ty)::(!res)) with Not_found -> ()) sign; !res ;; (* convertit l'arbre de preuve courant en ntree *) let to_nproof sigma osign pf = let rec to_nproof_rec sigma osign pf = let {evar_hyps=sign;evar_concl=cl} = pf.goal in let sign = Environ.named_context_of_val sign in let nsign = new_sign osign sign in let oldsign = old_sign osign sign in match pf.ref with None -> {t_info="to_prove"; t_goal=(seq_to_lnhyp oldsign nsign cl); t_proof=Notproved} | Some(r,spfl) -> if rule_is_complex r then ( let p1= to_nproof_rec sigma sign (subproof_of_proof pf) in let ntree= fill_unproved p1 (List.map (fun x -> (to_nproof_rec sigma sign x).t_proof) spfl) in (match r with Nested(Tactic (TacAtom (_, TacAuto _),_),_) -> if spfl=[] then {t_info="to_prove"; t_goal= {newhyp=[]; t_concl=concl ntree; t_full_concl=ntree.t_goal.t_full_concl; t_full_env=ntree.t_goal.t_full_env}; t_proof= Proof (TacAtom (dummy_loc,TacExtend (dummy_loc,"InfoAuto",[])), [ntree])} else ntree | _ -> ntree)) else {t_info="to_prove"; t_goal=(seq_to_lnhyp oldsign nsign cl); t_proof=(Proof (rule_to_ntactic r, List.map (fun x -> to_nproof_rec sigma sign x) spfl))} in update_closed (to_nproof_rec sigma osign pf) ;; (* recupere l'arbre de preuve courant. *) let get_nproof () = to_nproof (Global.env()) [] (Tacmach.proof_of_pftreestate (get_pftreestate())) ;; (*****************************************************************************) (* Pprinter *) let pr_void () = sphs "";; let list_rem l = match l with [] -> [] |x::l1->l1;; (* liste de chaines *) let prls l = let res = ref (sps (List.hd l)) in List.iter (fun s -> res:= sphv [ !res; spb; sps s]) (list_rem l); !res ;; let prphrases f l = spv (List.map (fun s -> sphv [f s; sps ","]) l) ;; (* indentation *) let spi = spnb 3;; (* en colonne *) let prl f l = if l=[] then spe else spv (List.map f l);; (*en colonne, avec indentation *) let prli f l = if l=[] then spe else sph [spi; spv (List.map f l)];; (* Langues. *) let rand l = List.nth l (Random.int (List.length l)) ;; type natural_languages = French | English;; let natural_language = ref French;; (*****************************************************************************) (* Les liens html pour proof-by-pointing *) (* le path du but en cours. *) let path=ref[1];; let ftag_apply =ref (fun (n:string) t -> spt t);; let ftag_case =ref (fun n -> sps n);; let ftag_elim =ref (fun n -> sps n);; let ftag_hypt =ref (fun h t -> sphypt (translate_path !path) h t);; let ftag_hyp =ref (fun h t -> sphyp (translate_path !path) h t);; let ftag_uselemma =ref (fun h t -> let intro = match !natural_language with French -> "par" | English -> "by" in spuselemma intro h t);; let ftag_toprove =ref (fun t -> sptoprove (translate_path !path) t);; let tag_apply = !ftag_apply;; let tag_case = !ftag_case;; let tag_elim = !ftag_elim;; let tag_uselemma = !ftag_uselemma;; let tag_hyp = !ftag_hyp;; let tag_hypt = !ftag_hypt;; let tag_toprove = !ftag_toprove;; (*****************************************************************************) (* pluriel *) let txtn n s = if n=1 then s else match s with |"un" -> "des" |"a" -> "" |"an" -> "" |"une" -> "des" |"Soit" -> "Soient" |"Let" -> "Let" | s -> s^"s" ;; let _et () = match !natural_language with French -> sps "et" | English -> sps "and" ;; let name_count = ref 0;; let new_name () = name_count:=(!name_count)+1; string_of_int !name_count ;; let enumerate f ln = match ln with [] -> [] | [x] -> [f x] |ln -> let rec enum_rec f ln = (match ln with [x;y] -> [f x; spb; sph [_et ();spb;f y]] |x::l -> [sph [(f x);sps ","];spb]@(enum_rec f l) | _ -> assert false) in enum_rec f ln ;; let constr_of_ast = Constrintern.interp_constr Evd.empty (Global.env());; let sp_tac tac = failwith "TODO" let soit_A_une_proposition nh ln t= match !natural_language with French -> sphv ([sps (txtn nh "Soit");spb]@(enumerate (fun x -> tag_hyp x t) ln) @[spb; prls [txtn nh "une";txtn nh "proposition"]]) | English -> sphv ([sps "Let";spb]@(enumerate (fun x -> tag_hyp x t) ln) @[spb; prls ["be"; txtn nh "a";txtn nh "proposition"]]) ;; let on_a ()= match !natural_language with French -> rand ["on a "] | English ->rand ["we have "] ;; let bon_a ()= match !natural_language with French -> rand ["On a "] | English ->rand ["We have "] ;; let soit_X_un_element_de_T nh ln t = match !natural_language with French -> sphv ([sps (txtn nh "Soit");spb]@(enumerate (fun x -> tag_hyp x t) ln) @[spb; prls [txtn nh "un";txtn nh "élément";"de"]] @[spb; spt t]) | English -> sphv ([sps (txtn nh "Let");spb]@(enumerate (fun x -> tag_hyp x t) ln) @[spb; prls ["be";txtn nh "an";txtn nh "element";"of"]] @[spb; spt t]) ;; let soit_F_une_fonction_de_type_T nh ln t = match !natural_language with French -> sphv ([sps (txtn nh "Soit");spb]@(enumerate (fun x -> tag_hyp x t) ln) @[spb; prls [txtn nh "une";txtn nh "fonction";"de";"type"]] @[spb; spt t]) | English -> sphv ([sps (txtn nh "Let");spb]@(enumerate (fun x -> tag_hyp x t) ln) @[spb; prls ["be";txtn nh "a";txtn nh "function";"of";"type"]] @[spb; spt t]) ;; let telle_que nh = match !natural_language with French -> [prls [" ";txtn nh "telle";"que";" "]] | English -> [prls [" "; "such";"that";" "]] ;; let tel_que nh = match !natural_language with French -> [prls [" ";txtn nh "tel";"que";" "]] | English -> [prls [" ";"such";"that";" "]] ;; let supposons () = match !natural_language with French -> "Supposons " | English -> "Suppose " ;; let cas () = match !natural_language with French -> "Cas" | English -> "Case" ;; let donnons_une_proposition () = match !natural_language with French -> sph[ (prls ["Donnons";"une";"proposition"])] | English -> sph[ (prls ["Let us give";"a";"proposition"])] ;; let montrons g = match !natural_language with French -> sph[ sps (rand ["Prouvons";"Montrons";"Démontrons"]); spb; spt g; sps ". "] | English -> sph[ sps (rand ["Let us";"Now"]);spb; sps (rand ["prove";"show"]); spb; spt g; sps ". "] ;; let calculons_un_element_de g = match !natural_language with French -> sph[ (prls ["Calculons";"un";"élément";"de"]); spb; spt g; sps ". "] | English -> sph[ (prls ["Let us";"compute";"an";"element";"of"]); spb; spt g; sps ". "] ;; let calculons_une_fonction_de_type g = match !natural_language with French -> sphv [ (prls ["Calculons";"une";"fonction";"de";"type"]); spb; spt g; sps ". "] | English -> sphv [ (prls ["Let";"us";"compute";"a";"function";"of";"type"]); spb; spt g; sps ". "];; let en_simplifiant_on_obtient g = match !natural_language with French -> sphv [ (prls [rand ["Après simplification,"; "En simplifiant,"]; rand ["on doit";"il reste à"]; rand ["prouver";"montrer";"démontrer"]]); spb; spt g; sps ". "] | English -> sphv [ (prls [rand ["After simplification,"; "Simplifying,"]; rand ["we must";"it remains to"]; rand ["prove";"show"]]); spb; spt g; sps ". "] ;; let on_obtient g = match !natural_language with French -> sph[ (prls [rand ["on doit";"il reste à"]; rand ["prouver";"montrer";"démontrer"]]); spb; spt g; sps ". "] | English ->sph[ (prls [rand ["we must";"it remains to"]; rand ["prove";"show"]]); spb; spt g; sps ". "] ;; let reste_a_montrer g = match !natural_language with French -> sph[ (prls ["Reste";"à"; rand ["prouver";"montrer";"démontrer"]]); spb; spt g; sps ". "] | English -> sph[ (prls ["It remains";"to"; rand ["prove";"show"]]); spb; spt g; sps ". "] ;; let discutons_avec_A type_arg = match !natural_language with French -> sphv [sps "Discutons"; spb; sps "avec"; spb; spt type_arg; sps ":"] | English -> sphv [sps "Let us discuss"; spb; sps "with"; spb; spt type_arg; sps ":"] ;; let utilisons_A arg1 = match !natural_language with French -> sphv [sps (rand ["Utilisons";"Avec";"A l'aide de"]); spb; spt arg1; sps ":"] | English -> sphv [sps (rand ["Let us use";"With";"With the help of"]); spb; spt arg1; sps ":"] ;; let selon_les_valeurs_de_A arg1 = match !natural_language with French -> sphv [ (prls ["Selon";"les";"valeurs";"de"]); spb; spt arg1; sps ":"] | English -> sphv [ (prls ["According";"values";"of"]); spb; spt arg1; sps ":"] ;; let de_A_on_a arg1 = match !natural_language with French -> sphv [ sps (rand ["De";"Avec";"Grâce à"]); spb; spt arg1; spb; sps (rand ["on a:";"on déduit:";"on obtient:"])] | English -> sphv [ sps (rand ["From";"With";"Thanks to"]); spb; spt arg1; spb; sps (rand ["we have:";"we deduce:";"we obtain:"])] ;; let procedons_par_recurrence_sur_A arg1 = match !natural_language with French -> sphv [ (prls ["Procédons";"par";"récurrence";"sur"]); spb; spt arg1; sps ":"] | English -> sphv [ (prls ["By";"induction";"on"]); spb; spt arg1; sps ":"] ;; let calculons_la_fonction_F_de_type_T_par_recurrence_sur_son_argument_A nfun tfun narg = match !natural_language with French -> sphv [ sphv [ prls ["Calculons";"la";"fonction"]; spb; sps (string_of_id nfun);spb; prls ["de";"type"]; spb; spt tfun;spb; prls ["par";"récurrence";"sur";"son";"argument"]; spb; sps (string_of_int narg); sps ":"] ] | English -> sphv [ sphv [ prls ["Let us compute";"the";"function"]; spb; sps (string_of_id nfun);spb; prls ["of";"type"]; spb; spt tfun;spb; prls ["by";"induction";"on";"its";"argument"]; spb; sps (string_of_int narg); sps ":"] ] ;; let pour_montrer_G_la_valeur_recherchee_est_A g arg1 = match !natural_language with French -> sph [sps "Pour";spb;sps "montrer"; spt g; spb; sps ","; spb; sps "choisissons";spb; spt arg1;sps ". " ] | English -> sph [sps "In order to";spb;sps "show"; spt g; spb; sps ","; spb; sps "let us choose";spb; spt arg1;sps ". " ] ;; let on_se_sert_de_A arg1 = match !natural_language with French -> sph [sps "On se sert de";spb ;spt arg1;sps ":" ] | English -> sph [sps "We use";spb ;spt arg1;sps ":" ] ;; let d_ou_A g = match !natural_language with French -> sph [spi; sps "d'où";spb ;spt g;sps ". " ] | English -> sph [spi; sps "then";spb ;spt g;sps ". " ] ;; let coq_le_demontre_seul () = match !natural_language with French -> rand [prls ["Coq";"le";"démontre"; "seul."]; sps "Fastoche."; sps "Trop cool"] | English -> rand [prls ["Coq";"shows";"it"; "alone."]; sps "Fingers in the nose."] ;; let de_A_on_deduit_donc_B arg g = match !natural_language with French -> sph [ sps "De"; spb; spt arg; spb; sps "on";spb; sps "déduit";spb; sps "donc";spb; spt g ] | English -> sph [ sps "From"; spb; spt arg; spb; sps "we";spb; sps "deduce";spb; sps "then";spb; spt g ] ;; let _A_est_immediat_par_B g arg = match !natural_language with French -> sph [ spt g; spb; (prls ["est";"immédiat";"par"]); spb; spt arg ] | English -> sph [ spt g; spb; (prls ["is";"immediate";"from"]); spb; spt arg ] ;; let le_resultat_est arg = match !natural_language with French -> sph [ (prls ["le";"résultat";"est"]); spb; spt arg ] | English -> sph [ (prls ["the";"result";"is"]); spb; spt arg ];; let on_applique_la_tactique tactic tac = match !natural_language with French -> sphv [ sps "on applique";spb;sps "la tactique"; spb;tactic;spb;tac] | English -> sphv [ sps "we apply";spb;sps "the tactic"; spb;tactic;spb;tac] ;; let de_A_il_vient_B arg g = match !natural_language with French -> sph [ sps "De"; spb; spt arg; spb; sps "il";spb; sps "vient";spb; spt g; sps ". " ] | English -> sph [ sps "From"; spb; spt arg; spb; sps "it";spb; sps "comes";spb; spt g; sps ". " ] ;; let ce_qui_est_trivial () = match !natural_language with French -> sps "Trivial." | English -> sps "Trivial." ;; let en_utilisant_l_egalite_A arg = match !natural_language with French -> sphv [ sps "En"; spb;sps "utilisant"; spb; sps "l'egalite"; spb; spt arg; sps "," ] | English -> sphv [ sps "Using"; spb; sps "the equality"; spb; spt arg; sps "," ] ;; let simplifions_H_T hyp thyp = match !natural_language with French -> sphv [sps"En simplifiant";spb;sps hyp;spb;sps "on obtient:"; spb;spt thyp;sps "."] | English -> sphv [sps"Simplifying";spb;sps hyp;spb;sps "we get:"; spb;spt thyp;sps "."] ;; let grace_a_A_il_suffit_de_montrer_LA arg lg= match !natural_language with French -> sphv ([sps (rand ["Grâce à";"Avec";"A l'aide de"]);spb; spt arg;sps ",";spb; sps "il suffit";spb; sps "de"; spb; sps (rand["prouver";"montrer";"démontrer"]); spb] @[spv (enumerate (fun x->x) lg)]) | English -> sphv ([sps (rand ["Thanks to";"With"]);spb; spt arg;sps ",";spb; sps "it suffices";spb; sps "to"; spb; sps (rand["prove";"show"]); spb] @[spv (enumerate (fun x->x) lg)]) ;; let reste_a_montrer_LA lg= match !natural_language with French -> sphv ([ sps "Il reste";spb; sps "à"; spb; sps (rand["prouver";"montrer";"démontrer"]); spb] @[spv (enumerate (fun x->x) lg)]) | English -> sphv ([ sps "It remains";spb; sps "to"; spb; sps (rand["prove";"show"]); spb] @[spv (enumerate (fun x->x) lg)]) ;; (*****************************************************************************) (* Traduction des hypothèses. *) type n_sort= Nprop | Nformula | Ntype | Nfunction ;; let sort_of_type t ts = let t=(strip_outer_cast t) in if is_Prop t then Nprop else match ts with Prop(Null) -> Nformula |_ -> (match (kind_of_term t) with Prod(_,_,_) -> Nfunction |_ -> Ntype) ;; let adrel (x,t) e = match x with Name(xid) -> Environ.push_rel (x,None,t) e | Anonymous -> Environ.push_rel (x,None,t) e let rec nsortrec vl x = match (kind_of_term x) with Prod(n,t,c)-> let vl = (adrel (n,t) vl) in nsortrec vl c | Lambda(n,t,c) -> let vl = (adrel (n,t) vl) in nsortrec vl c | App(f,args) -> nsortrec vl f | Sort(Prop(Null)) -> Prop(Null) | Sort(c) -> c | Ind(ind) -> let (mib,mip) = lookup_mind_specif vl ind in new_sort_in_family (inductive_sort_family mip) | Construct(c) -> nsortrec vl (mkInd (inductive_of_constructor c)) | Case(_,x,t,a) -> nsortrec vl x | Cast(x,_, t)-> nsortrec vl t | Const c -> nsortrec vl (Typeops.type_of_constant vl c) | _ -> nsortrec vl (type_of vl Evd.empty x) ;; let nsort x = nsortrec (Global.env()) (strip_outer_cast x) ;; let sort_of_hyp h = (sort_of_type h.hyp_type (nsort h.hyp_full_type)) ;; (* grouper les hypotheses successives de meme type, ou logiques. donne une liste de liste *) let rec group_lhyp lh = match lh with [] -> [] |[h] -> [[h]] |h::lh -> match group_lhyp lh with (h1::lh1)::lh2 -> if h.hyp_type=h1.hyp_type || ((sort_of_hyp h)=(sort_of_hyp h1) && (sort_of_hyp h1)=Nformula) then (h::(h1::lh1))::lh2 else [h]::((h1::lh1)::lh2) |_-> assert false ;; (* ln noms des hypotheses, lt leurs types *) let natural_ghyp (sort,ln,lt) intro = let t=List.hd lt in let nh=List.length ln in let _ns=List.hd ln in match sort with Nprop -> soit_A_une_proposition nh ln t | Ntype -> soit_X_un_element_de_T nh ln t | Nfunction -> soit_F_une_fonction_de_type_T nh ln t | Nformula -> sphv ((sps intro)::(enumerate (fun (n,t) -> tag_hypt n t) (List.combine ln lt))) ;; (* Cas d'une hypothese *) let natural_hyp h = let ns= string_of_id h.hyp_name in let t=h.hyp_type in let ts= (nsort h.hyp_full_type) in natural_ghyp ((sort_of_type t ts),[ns],[t]) (supposons ()) ;; let rec pr_ghyp lh intro= match lh with [] -> [] | [(sort,ln,t)]-> (match sort with Nformula -> [natural_ghyp(sort,ln,t) intro; sps ". "] | _ -> [natural_ghyp(sort,ln,t) ""; sps ". "]) | (sort,ln,t)::lh -> let hp= ([natural_ghyp(sort,ln,t) intro] @(match lh with [] -> [sps ". "] |(sort1,ln1,t1)::lh1 -> match sort1 with Nformula -> (let nh=List.length ln in match sort with Nprop -> telle_que nh |Nfunction -> telle_que nh |Ntype -> tel_que nh |Nformula -> [sps ". "]) | _ -> [sps ". "])) in (sphv hp)::(pr_ghyp lh "") ;; (* traduction d'une liste d'hypotheses groupees. *) let prnatural_ghyp llh intro= if llh=[] then spe else sphv (pr_ghyp (List.map (fun lh -> let h=(List.hd lh) in let sh = sort_of_hyp h in let lhname = (List.map (fun h -> string_of_id h.hyp_name) lh) in let lhtype = (List.map (fun h -> h.hyp_type) lh) in (sh,lhname,lhtype)) llh) intro) ;; (*****************************************************************************) (* Liste des hypotheses. *) type type_info_subgoals_hyp= All_subgoals_hyp | Reduce_hyp | No_subgoals_hyp | Case_subgoals_hyp of string (* word for introduction *) * Term.constr (* variable *) * string (* constructor *) * int (* arity *) * int (* number of constructors *) | Case_prop_subgoals_hyp of string (* word for introduction *) * Term.constr (* variable *) * int (* index of constructor *) * int (* arity *) * int (* number of constructors *) | Elim_subgoals_hyp of Term.constr (* variable *) * string (* constructor *) * int (* arity *) * (string list) (* rec hyp *) * int (* number of constructors *) | Elim_prop_subgoals_hyp of Term.constr (* variable *) * int (* index of constructor *) * int (* arity *) * (string list) (* rec hyp *) * int (* number of constructors *) ;; let rec nrem l n = if n<=0 then l else nrem (list_rem l) (n-1) ;; let rec nhd l n = if n<=0 then [] else (List.hd l)::(nhd (list_rem l) (n-1)) ;; let par_hypothese_de_recurrence () = match !natural_language with French -> sphv [(prls ["par";"hypothèse";"de";"récurrence";","])] | English -> sphv [(prls ["by";"induction";"hypothesis";","])] ;; let natural_lhyp lh hi = match hi with All_subgoals_hyp -> ( match lh with [] -> spe |_-> prnatural_ghyp (group_lhyp lh) (supposons ())) | Reduce_hyp -> (match lh with [h] -> simplifions_H_T (string_of_id h.hyp_name) h.hyp_type | _-> spe) | No_subgoals_hyp -> spe |Case_subgoals_hyp (sintro,var,c,a,ncase) -> (* sintro pas encore utilisee *) let s=ref c in for i=1 to a do let nh=(List.nth lh (i-1)) in s:=(!s)^" "^(string_of_id nh.hyp_name); done; if a>0 then s:="("^(!s)^")"; sphv [ (if ncase>1 then sph[ sps ("-"^(cas ()));spb] else spe); (* spt var;sps "="; *) sps !s; sps ":"; (prphrases (natural_hyp) (nrem lh a))] |Case_prop_subgoals_hyp (sintro,var,c,a,ncase) -> prnatural_ghyp (group_lhyp lh) sintro |Elim_subgoals_hyp (var,c,a,lhci,ncase) -> let nlh = List.length lh in let nlhci = List.length lhci in let lh0 = ref [] in for i=1 to (nlh-nlhci) do lh0:=(!lh0)@[List.nth lh (i-1)]; done; let lh=nrem lh (nlh-nlhci) in let s=ref c in let lh1=ref [] in for i=1 to nlhci do let targ=(List.nth lhci (i-1))in let nh=(List.nth lh (i-1)) in if targ="arg" || targ="argrec" then (s:=(!s)^" "^(string_of_id nh.hyp_name); lh0:=(!lh0)@[nh]) else lh1:=(!lh1)@[nh]; done; let introhyprec= (if (!lh1)=[] then spe else par_hypothese_de_recurrence () ) in if a>0 then s:="("^(!s)^")"; spv [sphv [(if ncase>1 then sph[ sps ("-"^(cas ()));spb] else spe); sps !s; sps ":"]; prnatural_ghyp (group_lhyp !lh0) (supposons ()); introhyprec; prl (natural_hyp) !lh1] |Elim_prop_subgoals_hyp (var,c,a,lhci,ncase) -> sphv [ (if ncase>1 then sph[ sps ("-"^(cas ()));spb;sps (string_of_int c); sps ":";spb] else spe); (prphrases (natural_hyp) lh )] ;; (*****************************************************************************) (* Analyse des tactiques. *) let name_tactic = function | TacIntroPattern _ -> "Intro" | TacAssumption -> "Assumption" | _ -> failwith "TODO" ;; (* let arg1_tactic tac = match tac with (Node(_,"Interp", (Node(_,_, (Node(_,_,x::_))::_))::_))::_ ->x | (Node(_,_,x::_))::_ -> x | x::_ -> x | _ -> assert false ;; *) let arg1_tactic tac = failwith "TODO";; type type_info_subgoals = {ihsg: type_info_subgoals_hyp; isgintro : string} ;; let rec show_goal lh ig g gs = match ig with "intros" -> if lh = [] then spe else show_goal lh "standard" g gs |"standard" -> (match (sort_of_type g gs) with Nprop -> donnons_une_proposition () | Nformula -> montrons g | Ntype -> calculons_un_element_de g | Nfunction ->calculons_une_fonction_de_type g) | "apply" -> show_goal lh "" g gs | "simpl" ->en_simplifiant_on_obtient g | "rewrite" -> on_obtient g | "equality" -> reste_a_montrer g | "trivial_equality" -> reste_a_montrer g | "" -> spe |_ -> sph[ sps "A faire ..."; spb; spt g; sps ". " ] ;; let show_goal2 lh {ihsg=hi;isgintro=ig} g gs s = if ig="" && lh = [] then spe else sphv [ show_goal lh ig g gs; sps s] ;; let imaginez_une_preuve_de () = match !natural_language with French -> "Imaginez une preuve de" | English -> "Imagine a proof of" ;; let donnez_un_element_de () = match !natural_language with French -> "Donnez un element de" | English -> "Give an element of";; let intro_not_proved_goal gs = match gs with Prop(Null) -> imaginez_une_preuve_de () |_ -> donnez_un_element_de () ;; let first_name_hyp_of_ntree {t_goal={newhyp=lh}}= match lh with {hyp_name=n}::_ -> n | _ -> assert false ;; let rec find_type x t= match (kind_of_term (strip_outer_cast t)) with Prod(y,ty,t) -> (match y with Name y -> if x=(string_of_id y) then ty else find_type x t | _ -> find_type x t) |_-> assert false ;; (*********************************************************************** Traitement des égalités *) (* let is_equality e = match (kind_of_term e) with AppL args -> (match (kind_of_term args.(0)) with Const (c,_) -> (match (string_of_sp c) with "Equal" -> true | "eq" -> true | "eqT" -> true | "identityT" -> true | _ -> false) | _ -> false) | _ -> false ;; *) let is_equality e = let e= (strip_outer_cast e) in match (kind_of_term e) with App (f,args) -> (Array.length args) >= 3 | _ -> false ;; let terms_of_equality e = let e= (strip_outer_cast e) in match (kind_of_term e) with App (f,args) -> (args.(1) , args.(2)) | _ -> assert false ;; let eq_term = eq_constr;; let is_equality_tac = function | TacAtom (_, (TacExtend (_,("ERewriteLR"|"ERewriteRL"|"ERewriteLRocc"|"ERewriteRLocc" |"ERewriteParallel"|"ERewriteNormal" |"RewriteLR"|"RewriteRL"|"Replace"),_) | TacReduce _ | TacSymmetry _ | TacReflexivity | TacExact _ | TacIntroPattern _ | TacIntroMove _ | TacAuto _)) -> true | _ -> false let equalities_ntree ig ntree = let rec equalities_ntree ig ntree = if not (is_equality (concl ntree)) then [] else match (proof ntree) with Notproved -> [(ig,ntree)] | Proof (tac,ltree) -> if is_equality_tac tac then (match ltree with [] -> [(ig,ntree)] | t::_ -> let res=(equalities_ntree ig t) in if eq_term (concl ntree) (concl t) then res else (ig,ntree)::res) else [(ig,ntree)] in equalities_ntree ig ntree ;; let remove_seq_of_terms l = let rec remove_seq_of_terms l = match l with a::b::l -> if (eq_term (fst a) (fst b)) then remove_seq_of_terms (b::l) else a::(remove_seq_of_terms (b::l)) | _ -> l in remove_seq_of_terms l ;; let list_to_eq l o= let switch = fun h h' -> (if o then h else h') in match l with [a] -> spt (fst a) | (a,h)::(b,h')::l -> let rec list_to_eq h l = match l with [] -> [] | (b,h')::l -> (sph [sps "="; spb; spt b; spb;tag_uselemma (switch h h') spe]) :: (list_to_eq (switch h' h) l) in sph [spt a; spb; spv ((sph [sps "="; spb; spt b; spb; tag_uselemma (switch h h') spe]) ::(list_to_eq (switch h' h) l))] | _ -> assert false ;; let stde = Global.env;; let dbize env = Constrintern.interp_constr Evd.empty env;; (**********************************************************************) let rec natural_ntree ig ntree = let {t_info=info; t_goal={newhyp=lh;t_concl=g;t_full_concl=gf;t_full_env=ge}; t_proof=p} = ntree in let leq = List.rev (equalities_ntree ig ntree) in if List.length leq > 1 then (* Several equalities to treate ... *) ( print_string("Several equalities to treate ...\n"); let l1 = ref [] in let l2 = ref [] in List.iter (fun (_,ntree) -> let lemma = match (proof ntree) with Proof (tac,ltree) -> (try (sph [spt (dbize (gLOB ge) (arg1_tactic tac));(* TODO *) (match ltree with [] ->spe | [_] -> spe | _::l -> sphv[sps ": "; prli (natural_ntree {ihsg=All_subgoals_hyp; isgintro="standard"}) l])]) with _ -> sps "simplification" ) | Notproved -> spe in let (t1,t2)= terms_of_equality (concl ntree) in l2:=(t2,lemma)::(!l2); l1:=(t1,lemma)::(!l1)) leq; l1:=remove_seq_of_terms !l1; l2:=remove_seq_of_terms !l2; l2:=List.rev !l2; let ltext=ref [] in if List.length !l1 > 1 then (ltext:=(!ltext)@[list_to_eq !l1 true]; if List.length !l2 > 1 then (ltext:=(!ltext)@[_et()]; ltext:=(!ltext)@[list_to_eq !l2 false])) else if List.length !l2 > 1 then ltext:=(!ltext)@[list_to_eq !l2 false]; if !ltext<>[] then ltext:=[sps (bon_a ()); spv !ltext]; let (ig,ntree)=(List.hd leq) in spv [(natural_lhyp lh ig.ihsg); (show_goal2 lh ig g (nsort gf) ""); sph !ltext; natural_ntree {ihsg=All_subgoals_hyp; isgintro= let (t1,t2)= terms_of_equality (concl ntree) in if eq_term t1 t2 then "trivial_equality" else "equality"} ntree] ) else let ntext = let gs=nsort gf in match p with Notproved -> spv [ (natural_lhyp lh ig.ihsg); sph [spi; sps (intro_not_proved_goal gs); spb; tag_toprove g ] ] | Proof (TacId _,ltree) -> natural_ntree ig (List.hd ltree) | Proof (TacAtom (_,tac),ltree) -> (let ntext = match tac with (* Pas besoin de l'argument éventuel de la tactique *) TacIntroPattern _ -> natural_intros ig lh g gs ltree | TacIntroMove _ -> natural_intros ig lh g gs ltree | TacFix (_,n) -> natural_fix ig lh g gs n ltree | TacSplit (_,_,NoBindings) -> natural_split ig lh g gs ge [] ltree | TacSplit(_,_,ImplicitBindings l) -> natural_split ig lh g gs ge (List.map snd l) ltree | TacGeneralize l -> natural_generalize ig lh g gs ge l ltree | TacRight _ -> natural_right ig lh g gs ltree | TacLeft _ -> natural_left ig lh g gs ltree | (* "Simpl" *)TacReduce (r,cl) -> natural_reduce ig lh g gs ge r cl ltree | TacExtend (_,"InfoAuto",[]) -> natural_infoauto ig lh g gs ltree | TacAuto _ -> natural_auto ig lh g gs ltree | TacExtend (_,"EAuto",_) -> natural_auto ig lh g gs ltree | TacTrivial _ -> natural_trivial ig lh g gs ltree | TacAssumption -> natural_trivial ig lh g gs ltree | TacClear _ -> natural_clear ig lh g gs ltree (* Besoin de l'argument de la tactique *) | TacSimpleInductionDestruct (true,NamedHyp id) -> natural_induction ig lh g gs ge id ltree false | TacExtend (_,"InductionIntro",[a]) -> let id=(out_gen wit_ident a) in natural_induction ig lh g gs ge id ltree true | TacApply (_,false,[c,_]) -> natural_apply ig lh g gs (snd c) ltree | TacExact c -> natural_exact ig lh g gs (snd c) ltree | TacCut c -> natural_cut ig lh g gs (snd c) ltree | TacExtend (_,"CutIntro",[a]) -> let _c = out_gen wit_constr a in natural_cutintro ig lh g gs a ltree | TacCase (_,(c,_)) -> natural_case ig lh g gs ge (snd c) ltree false | TacExtend (_,"CaseIntro",[a]) -> let c = out_gen wit_constr a in natural_case ig lh g gs ge c ltree true | TacElim (_,(c,_),_) -> natural_elim ig lh g gs ge (snd c) ltree false | TacExtend (_,"ElimIntro",[a]) -> let c = out_gen wit_constr a in natural_elim ig lh g gs ge c ltree true | TacExtend (_,"Rewrite",[_;a]) -> let (c,_) = out_gen wit_constr_with_bindings a in natural_rewrite ig lh g gs c ltree | TacExtend (_,"ERewriteRL",[a]) -> let c = out_gen wit_constr a in (* TODO *) natural_rewrite ig lh g gs c ltree | TacExtend (_,"ERewriteLR",[a]) -> let c = out_gen wit_constr a in (* TODO *) natural_rewrite ig lh g gs c ltree |_ -> natural_generic ig lh g gs (sps (name_tactic tac)) (prl sp_tac [tac]) ltree in ntext (* spwithtac ntext tactic*) ) | Proof _ -> failwith "Don't know what to do with that" in if info<>"not_proved" then spshrink info ntext else ntext and natural_generic ig lh g gs tactic tac ltree = spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); on_applique_la_tactique tactic tac ; (prli(natural_ntree {ihsg=All_subgoals_hyp; isgintro="standard"}) ltree) ] and natural_clear ig lh g gs ltree = natural_ntree ig (List.hd ltree) (* spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); (prl (natural_ntree ig) ltree) ] *) and natural_intros ig lh g gs ltree = spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); (prl (natural_ntree {ihsg=All_subgoals_hyp; isgintro="intros"}) ltree) ] and natural_apply ig lh g gs arg ltree = let lg = List.map concl ltree in match lg with [] -> spv [ (natural_lhyp lh ig.ihsg); de_A_il_vient_B arg g ] | [sg]-> spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh {ihsg=ig.ihsg; isgintro= if ig.isgintro<>"apply" then "standard" else ""} g gs ""); grace_a_A_il_suffit_de_montrer_LA arg [spt sg]; sph [spi ; natural_ntree {ihsg=All_subgoals_hyp; isgintro="apply"} (List.hd ltree)] ] | _ -> let ln = List.map (fun _ -> new_name()) lg in spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh {ihsg=ig.ihsg; isgintro= if ig.isgintro<>"apply" then "standard" else ""} g gs ""); grace_a_A_il_suffit_de_montrer_LA arg (List.map2 (fun g n -> sph [sps ("("^n^")"); spb; spt g]) lg ln); sph [spi; spv (List.map2 (fun x n -> sph [sps ("("^n^"):"); spb; natural_ntree {ihsg=All_subgoals_hyp; isgintro="apply"} x]) ltree ln)] ] and natural_rem_goals ltree = let lg = List.map concl ltree in match lg with [] -> spe | [sg]-> spv [ reste_a_montrer_LA [spt sg]; sph [spi ; natural_ntree {ihsg=All_subgoals_hyp; isgintro="apply"} (List.hd ltree)] ] | _ -> let ln = List.map (fun _ -> new_name()) lg in spv [ reste_a_montrer_LA (List.map2 (fun g n -> sph [sps ("("^n^")"); spb; spt g]) lg ln); sph [spi; spv (List.map2 (fun x n -> sph [sps ("("^n^"):"); spb; natural_ntree {ihsg=All_subgoals_hyp; isgintro="apply"} x]) ltree ln)] ] and natural_exact ig lh g gs arg ltree = spv [ (natural_lhyp lh ig.ihsg); (let {ihsg=pi;isgintro=ig}= ig in (show_goal2 lh {ihsg=pi;isgintro=""} g gs "")); (match gs with Prop(Null) -> _A_est_immediat_par_B g arg |_ -> le_resultat_est arg) ] and natural_cut ig lh g gs arg ltree = spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); (prli(natural_ntree {ihsg=All_subgoals_hyp;isgintro="standard"}) (List.rev ltree)); de_A_on_deduit_donc_B arg g ] and natural_cutintro ig lh g gs arg ltree = spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); sph [spi; (natural_ntree {ihsg=All_subgoals_hyp;isgintro=""} (List.nth ltree 1))]; sph [spi; (natural_ntree {ihsg=No_subgoals_hyp;isgintro=""} (List.nth ltree 0))] ] and whd_betadeltaiota x = whd_betaiotaevar (Global.env()) Evd.empty x and type_of_ast s c = type_of (Global.env()) Evd.empty (constr_of_ast c) and prod_head t = match (kind_of_term (strip_outer_cast t)) with Prod(_,_,c) -> prod_head c (* |App(f,a) -> f *) | _ -> t and string_of_sp sp = string_of_id (basename sp) and constr_of_mind mip i = (string_of_id mip.mind_consnames.(i-1)) and arity_of_constr_of_mind env indf i = (get_constructors env indf).(i-1).cs_nargs and gLOB ge = Global.env_of_context ge (* (Global.env()) *) and natural_case ig lh g gs ge arg1 ltree with_intros = let env= (gLOB ge) in let targ1 = prod_head (type_of env Evd.empty arg1) in let IndType (indf,targ) = find_rectype env Evd.empty targ1 in let ncti= Array.length(get_constructors env indf) in let (ind,_) = dest_ind_family indf in let (mib,mip) = lookup_mind_specif env ind in let ti =(string_of_id mip.mind_typename) in let type_arg= targ1 (* List.nth targ (mis_index dmi)*) in if ncti<>1 (* Zéro ou Plusieurs constructeurs *) then ( spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); (match (nsort targ1) with Prop(Null) -> (match ti with "or" -> discutons_avec_A type_arg | _ -> utilisons_A arg1) |_ -> selon_les_valeurs_de_A arg1); (let ci=ref 0 in (prli (fun treearg -> ci:=!ci+1; let nci=(constr_of_mind mip !ci) in let aci=if with_intros then (arity_of_constr_of_mind env indf !ci) else 0 in let ici= (!ci) in sph[ (natural_ntree {ihsg= (match (nsort targ1) with Prop(Null) -> Case_prop_subgoals_hyp (supposons (),arg1,ici,aci, (List.length ltree)) |_-> Case_subgoals_hyp ("",arg1,nci,aci, (List.length ltree))); isgintro= if with_intros then "" else "standard"} treearg) ]) (nrem ltree ((List.length ltree)- ncti)))); (sph [spi; (natural_rem_goals (nhd ltree ((List.length ltree)- ncti)))]) ] ) (* Cas d'un seul constructeur *) else ( spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); de_A_on_a arg1; (let treearg=List.hd ltree in let nci=(constr_of_mind mip 1) in let aci= if with_intros then (arity_of_constr_of_mind env indf 1) else 0 in let _ici= 1 in sph[ (natural_ntree {ihsg= (match (nsort targ1) with Prop(Null) -> Case_prop_subgoals_hyp ("",arg1,1,aci, (List.length ltree)) |_-> Case_subgoals_hyp ("",arg1,nci,aci, (List.length ltree))); isgintro=""} treearg) ]); (sph [spi; (natural_rem_goals (nhd ltree ((List.length ltree)- 1)))]) ] ) (* with _ ->natural_generic ig lh g gs (sps "Case") (spt arg1) ltree *) (*****************************************************************************) (* Elim *) and prod_list_var t = match (kind_of_term (strip_outer_cast t)) with Prod(_,t,c) -> t::(prod_list_var c) |_ -> [] and hd_is_mind t ti = try (let env = Global.env() in let IndType (indf,targ) = find_rectype env Evd.empty t in let _ncti= Array.length(get_constructors env indf) in let (ind,_) = dest_ind_family indf in let (mib,mip) = lookup_mind_specif env ind in (string_of_id mip.mind_typename) = ti) with _ -> false and mind_ind_info_hyp_constr indf c = let env = Global.env() in let (ind,_) = dest_ind_family indf in let (mib,mip) = lookup_mind_specif env ind in let _p = mib.mind_nparams in let a = arity_of_constr_of_mind env indf c in let lp=ref (get_constructors env indf).(c).cs_args in let lr=ref [] in let ti = (string_of_id mip.mind_typename) in for i=1 to a do match !lp with ((_,_,t)::lp1)-> if hd_is_mind t ti then (lr:=(!lr)@["argrec";"hyprec"]; lp:=List.tl lp1) else (lr:=(!lr)@["arg"];lp:=lp1) | _ -> raise (Failure "mind_ind_info_hyp_constr") done; !lr (* mind_ind_info_hyp_constr "le" 2;; donne ["arg"; "argrec"] mind_ind_info_hyp_constr "le" 1;; donne [] mind_ind_info_hyp_constr "nat" 2;; donne ["argrec"] *) and natural_elim ig lh g gs ge arg1 ltree with_intros= let env= (gLOB ge) in let targ1 = prod_head (type_of env Evd.empty arg1) in let IndType (indf,targ) = find_rectype env Evd.empty targ1 in let ncti= Array.length(get_constructors env indf) in let (ind,_) = dest_ind_family indf in let (mib,mip) = lookup_mind_specif env ind in let _ti =(string_of_id mip.mind_typename) in let _type_arg=targ1 (* List.nth targ (mis_index dmi) *) in spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); (match (nsort targ1) with Prop(Null) -> utilisons_A arg1 |_ ->procedons_par_recurrence_sur_A arg1); (let ci=ref 0 in (prli (fun treearg -> ci:=!ci+1; let nci=(constr_of_mind mip !ci) in let aci=(arity_of_constr_of_mind env indf !ci) in let hci= if with_intros then mind_ind_info_hyp_constr indf !ci else [] in let ici= (!ci) in sph[ (natural_ntree {ihsg= (match (nsort targ1) with Prop(Null) -> Elim_prop_subgoals_hyp (arg1,ici,aci,hci, (List.length ltree)) |_-> Elim_subgoals_hyp (arg1,nci,aci,hci, (List.length ltree))); isgintro= ""} treearg) ]) (nhd ltree ncti))); (sph [spi; (natural_rem_goals (nrem ltree ncti))]) ] (* ) with _ ->natural_generic ig lh g gs (sps "Elim") (spt arg1) ltree *) (*****************************************************************************) (* InductionIntro n *) and natural_induction ig lh g gs ge arg2 ltree with_intros= let env = (gLOB (g_env (List.hd ltree))) in let arg1= mkVar arg2 in let targ1 = prod_head (type_of env Evd.empty arg1) in let IndType (indf,targ) = find_rectype env Evd.empty targ1 in let _ncti= Array.length(get_constructors env indf) in let (ind,_) = dest_ind_family indf in let (mib,mip) = lookup_mind_specif env ind in let _ti =(string_of_id mip.mind_typename) in let _type_arg= targ1(*List.nth targ (mis_index dmi)*) in let lh1= hyps (List.hd ltree) in (* la liste des hyp jusqu'a n *) (* on les enleve des hypotheses des sous-buts *) let ltree = List.map (fun {t_info=info; t_goal={newhyp=lh;t_concl=g;t_full_concl=gf;t_full_env=ge}; t_proof=p} -> {t_info=info; t_goal={newhyp=(nrem lh (List.length lh1)); t_concl=g;t_full_concl=gf;t_full_env=ge}; t_proof=p}) ltree in spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); (natural_lhyp lh1 All_subgoals_hyp); (match (print_string "targ1------------\n";(nsort targ1)) with Prop(Null) -> utilisons_A arg1 |_ -> procedons_par_recurrence_sur_A arg1); (let ci=ref 0 in (prli (fun treearg -> ci:=!ci+1; let nci=(constr_of_mind mip !ci) in let aci=(arity_of_constr_of_mind env indf !ci) in let hci= if with_intros then mind_ind_info_hyp_constr indf !ci else [] in let ici= (!ci) in sph[ (natural_ntree {ihsg= (match (nsort targ1) with Prop(Null) -> Elim_prop_subgoals_hyp (arg1,ici,aci,hci, (List.length ltree)) |_-> Elim_subgoals_hyp (arg1,nci,aci,hci, (List.length ltree))); isgintro= "standard"} treearg) ]) ltree)) ] (************************************************************************) (* Points fixes *) and natural_fix ig lh g gs narg ltree = let {t_info=info; t_goal={newhyp=lh1;t_concl=g1;t_full_concl=gf1; t_full_env=ge1};t_proof=p1}=(List.hd ltree) in match lh1 with {hyp_name=nfun;hyp_type=tfun}::lh2 -> let ltree=[{t_info=info; t_goal={newhyp=lh2;t_concl=g1;t_full_concl=gf1; t_full_env=ge1}; t_proof=p1}] in spv [ (natural_lhyp lh ig.ihsg); calculons_la_fonction_F_de_type_T_par_recurrence_sur_son_argument_A nfun tfun narg; (prli(natural_ntree {ihsg=All_subgoals_hyp;isgintro=""}) ltree) ] | _ -> assert false and natural_reduce ig lh g gs ge mode la ltree = match la with {onhyps=Some[]} when la.concl_occs <> no_occurrences_expr -> spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); (prl (natural_ntree {ihsg=All_subgoals_hyp;isgintro="simpl"}) ltree) ] | {onhyps=Some[hyp]} when la.concl_occs = no_occurrences_expr -> spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); (prl (natural_ntree {ihsg=Reduce_hyp;isgintro=""}) ltree) ] | _ -> assert false and natural_split ig lh g gs ge la ltree = match la with [arg] -> let _env= (gLOB ge) in let arg1= (*dbize _env*) arg in spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); pour_montrer_G_la_valeur_recherchee_est_A g arg1; (prl (natural_ntree {ihsg=All_subgoals_hyp;isgintro="standard"}) ltree) ] | [] -> spv [ (natural_lhyp lh ig.ihsg); (prli(natural_ntree {ihsg=All_subgoals_hyp;isgintro="standard"}) ltree) ] | _ -> assert false and natural_generalize ig lh g gs ge la ltree = match la with [(_,(_,arg)),_] -> let _env= (gLOB ge) in let arg1= (*dbize env*) arg in let _type_arg=type_of (Global.env()) Evd.empty arg in (* let type_arg=type_of_ast ge arg in*) spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); on_se_sert_de_A arg1; (prl (natural_ntree {ihsg=All_subgoals_hyp;isgintro=""}) ltree) ] | _ -> assert false and natural_right ig lh g gs ltree = spv [ (natural_lhyp lh ig.ihsg); (prli(natural_ntree {ihsg=All_subgoals_hyp;isgintro="standard"}) ltree); d_ou_A g ] and natural_left ig lh g gs ltree = spv [ (natural_lhyp lh ig.ihsg); (prli(natural_ntree {ihsg=All_subgoals_hyp;isgintro="standard"}) ltree); d_ou_A g ] and natural_auto ig lh g gs ltree = match ig.isgintro with "trivial_equality" -> spe | _ -> if ltree=[] then sphv [(natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); coq_le_demontre_seul ()] else spv [(natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); (prli (natural_ntree {ihsg=All_subgoals_hyp;isgintro=""} ) ltree)] and natural_infoauto ig lh g gs ltree = match ig.isgintro with "trivial_equality" -> spshrink "trivial_equality" (natural_ntree {ihsg=All_subgoals_hyp;isgintro="standard"} (List.hd ltree)) | _ -> sphv [(natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); coq_le_demontre_seul (); spshrink "auto" (sph [spi; (natural_ntree {ihsg=All_subgoals_hyp;isgintro=""} (List.hd ltree))])] and natural_trivial ig lh g gs ltree = if ltree=[] then sphv [(natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); ce_qui_est_trivial () ] else spv [(natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ". "); (prli(natural_ntree {ihsg=All_subgoals_hyp;isgintro="standard"}) ltree)] and natural_rewrite ig lh g gs arg ltree = spv [ (natural_lhyp lh ig.ihsg); (show_goal2 lh ig g gs ""); en_utilisant_l_egalite_A arg; (prli(natural_ntree {ihsg=All_subgoals_hyp;isgintro="rewrite"}) ltree) ] ;; let natural_ntree_path ig g = Random.init(0); natural_ntree ig g ;; let show_proof lang gpath = (match lang with "fr" -> natural_language:=French |"en" -> natural_language:=English | _ -> natural_language:=English); path:=List.rev gpath; name_count:=0; let ntree=(get_nproof ()) in let {t_info=i;t_goal=g;t_proof=p} =ntree in root_of_text_proof (sph [(natural_ntree_path {ihsg=All_subgoals_hyp; isgintro="standard"} {t_info="not_proved";t_goal=g;t_proof=p}); spr]) ;; let show_nproof path = pp (sp_print (sph [spi; show_proof "fr" path]));; vinterp_add "ShowNaturalProof" (fun _ -> (fun () ->show_nproof[];()));; (*********************************************************************** debug sous cygwin: PATH=/usr/local/bin:/usr/bin:$PATH COQTOP=d:/Tools/coq-7avril CAMLLIB=/usr/local/lib/ocaml CAMLP4LIB=/usr/local/lib/camlp4 export CAMLLIB export COQTOP export CAMLP4LIB cd d:/Tools/pcoq/src/text d:/Tools/coq-7avril/bin/coqtop.byte.exe -I /cygdrive/D/Tools/pcoq/src/abs_syntax -I /cygdrive/D/Tools/pcoq/src/text -I /cygdrive/D/Tools/pcoq/src/coq -I /cygdrive/D/Tools/pcoq/src/pbp -I /cygdrive/D/Tools/pcoq/src/dad -I /cygdrive/D/Tools/pcoq/src/history Lemma l1: (A, B : Prop) A \/ B -> B -> A. Intros. Elim H. Auto. Qed. Drop. #use "/cygdrive/D/Tools/coq-7avril/dev/base_include";; #load "xlate.cmo";; #load "translate.cmo";; #load "showproof_ct.cmo";; #load "showproof.cmo";; #load "pbp.cmo";; #load "debug_tac.cmo";; #load "name_to_ast.cmo";; #load "paths.cmo";; #load "dad.cmo";; #load "vtp.cmo";; #load "history.cmo";; #load "centaur.cmo";; Xlate.set_xlate_mut_stuff Centaur.globcv;; Xlate.declare_in_coq();; #use "showproof.ml";; let pproof x = pP (sp_print x);; Pp_control.set_depth_boxes 100;; #install_printer pproof;; ep();; let bidon = ref (constr_of_string "O");; #trace to_nproof;; ***********************************************************************) let ep()=show_proof "fr" [];;