From 5263518b921801f0c5299ca67708a8f79325c2e9 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Fri, 19 Mar 2021 17:03:42 -0700 Subject: [PATCH 01/39] Remove second pass in minimal/sound variant --- src/coq/decompiler/decompiler.ml | 90 +++----------------------------- 1 file changed, 7 insertions(+), 83 deletions(-) diff --git a/src/coq/decompiler/decompiler.ml b/src/coq/decompiler/decompiler.ml index 314ff57..f41b712 100644 --- a/src/coq/decompiler/decompiler.ml +++ b/src/coq/decompiler/decompiler.ml @@ -15,6 +15,12 @@ open Zooming open Nameutils open Ltac_plugin open Stateutils + +(* + * This is a minimal, sound version of the decompiler with our own heuristics + * and improvements disabled. We can add those back later, but I think it's + * easier to start with this to experiment with the decompiler. + *) (* Monadic bind on option types. *) let (>>=) = Option.bind @@ -177,87 +183,6 @@ let dot tac next = Some (Compose ([ tac ], [ next ])) (* Single tactic to finish proof. *) let qed tac = Some (Compose ([ tac ], [])) -(* Inserts "simpl." before every rewrite. *) -let rec simpl sigma (t : tactical) : tactical = - match t with - (*| Compose ( [ Rewrite (env, b, c, Some goal) ], goal_prfs) -> - let r = Rewrite (env, b, c, Some goal) in - let rest = Compose ([ r ], List.map (simpl sigma) goal_prfs) in - (try - Printing.debug_term env b "REWRITE: "; - Printing.debug_term env goal "GOAL: "; - let goals1, sigma = run_tac env sigma (coq_tac sigma r "") goal in - let goals2, sigma = run_tac env sigma (coq_tac sigma r "simpl;") goal in - let goals1 = List.map (Goal.V82.abstract_type sigma) goals1 in - let goals2 = List.map (Goal.V82.abstract_type sigma) goals2 in - if list_eq (EConstr.eq_constr sigma) goals1 goals2 - then rest else Compose ([ Simpl ], [ rest ]) - with _ -> rest) *) - | Compose ( [ Rewrite (a, b, c, d) ], goals) -> - Compose ([ Simpl ], [ Compose ([ Rewrite (a, b, c, d) ], - List.map (simpl sigma) goals)]) - | Compose (tacs, goals) -> - Compose (tacs, List.map (simpl sigma) goals) - - -(* Combine adjacent intros and revert tactics if possible. *) -let rec intros_revert (t : tactical) : tactical = - match t with - | Compose ( [ Intros xs ], [ Compose ([ Revert ys ], goals) ]) -> - let n = count_shared_prefix Id.equal (List.rev xs) ys in - let xs' = take (List.length xs - n) xs in - let ys' = drop n ys in - let goals' = List.map intros_revert goals in - (* Don't include empty name lists! *) - let c1 = if ys' == [] then goals' else [ Compose ([ Revert ys' ], goals') ] in - if xs' == [] then List.hd c1 else Compose ([ Intros xs' ], c1) - | Compose (tacs, goals) -> - Compose (tacs, List.map intros_revert goals) - -(* Combine common subgoal tactics into semicolons. *) -let rec semicolons sigma (t : tactical) : tactical = - let first t = match t with - | Compose ( [ tac ], _) -> tac in - let subgoals t = match t with - | Compose ( _, goals) -> goals in - match t with - (* end of proof *) - | Compose (_, []) -> t - (* single subgoal, don't bother *) - | Compose ( tacs, [ goal ]) -> - Compose ( tacs, [ semicolons sigma goal ]) - (* compare first tactic of each subgoal *) - | Compose ( tacs, goals ) -> - let firsts = List.map first goals in - if all_eq (compare_tact sigma) firsts - then - let goals' = List.concat (List.map subgoals goals) in - semicolons sigma (Compose ( (List.hd firsts) :: tacs, goals')) - else - Compose (tacs, List.map (semicolons sigma) goals) - -(* Try implicit arguments to rewrite functions. *) -let rec rewrite_implicit sigma (t : tactical) : tactical = - try - match t with - | Compose ( [ Rewrite (env, fx, dir, Some goal) ], [ goal_prf ]) -> - let rest = [ rewrite_implicit sigma goal_prf ] in - let r1 = Rewrite (env, fx, dir, Some goal) in - (match kind fx with - | App (f, args) -> - let r2 = Rewrite (env, f, dir, Some goal) in - let goals1, sigma = run_tac env sigma (coq_tac sigma r1 "") goal in - let goals2, sigma = run_tac env sigma (coq_tac sigma r2 "") goal in - let goals1 = List.map (Goal.V82.abstract_type sigma) goals1 in - let goals2 = List.map (Goal.V82.abstract_type sigma) goals2 in - let choice = if list_eq (EConstr.eq_constr sigma) goals1 goals2 - then r2 else r1 in - Compose ( [ choice ], rest ) - | _ -> Compose ( [ r1 ], rest )) - | Compose ( tacs, goals ) -> - Compose ( tacs, List.map (rewrite_implicit sigma) goals ) - with _ -> t - (* Given the list of tactics and their corresponding string expressions, try to solve the goal (type of trm), return None otherwise. *) @@ -481,8 +406,7 @@ and pose (n, valu, t, body) (env, sigma, opts) : tactical option = (* Decompile a term into its equivalent tactic list. *) let tac_from_term env sigma opts trm : tactical = - (* Perform second pass to revise greedy tactic list. *) - semicolons sigma (simpl sigma (rewrite_implicit sigma (intros_revert (first_pass env sigma opts trm)))) + first_pass env sigma opts trm (* Generate indentation space before bullet. *) let indent level = From 61757859c8cdb298aaf88b337ccddcae5fbe1a6b Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Fri, 19 Mar 2021 18:02:42 -0700 Subject: [PATCH 02/39] Remove extra functions --- src/coq/decompiler/decompiler.ml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/coq/decompiler/decompiler.ml b/src/coq/decompiler/decompiler.ml index f41b712..35be7d4 100644 --- a/src/coq/decompiler/decompiler.ml +++ b/src/coq/decompiler/decompiler.ml @@ -138,18 +138,6 @@ let show_tactic sigma tac : Pp.t = | Auto -> str "auto" | Expr s -> str s -(* Convert IR tactic to coq tactic by printing and parsing. *) -let coq_tac sigma t prefix = - let s = show_tactic sigma t in - let s' = Format.asprintf "%a" Pp.pp_with s in - parse_tac_str (prefix ^ s') - -(* True if both tactics are "equal" (syntactically). *) -let compare_tact sigma (t1 : tact) (t2 : tact) : bool = - let s1 = show_tactic sigma t1 in - let s2 = show_tactic sigma t2 in - Pp.string_of_ppcmds s1 = Pp.string_of_ppcmds s2 - (* Option monad over function application. *) let try_app (trm : constr) : (constr * constr array) option = match kind trm with @@ -211,8 +199,6 @@ let apply_implicit env sigma trm = qed tac with _ -> None - - (* Performs the bulk of decompilation on a proof term. Opts are the optional goal solving tactics that can be inserted into the generated script. If one of these tactics solves the focused goal or From 82d173d87da6d9f6e17fd08add22c5bfebfd2c27 Mon Sep 17 00:00:00 2001 From: RanDair Porter Date: Fri, 9 Apr 2021 09:27:16 -0700 Subject: [PATCH 03/39] Threading state --- src/coq/decompiler/decompiler.ml | 104 +++++++++++++++++------------- src/coq/decompiler/decompiler.mli | 2 +- 2 files changed, 59 insertions(+), 47 deletions(-) diff --git a/src/coq/decompiler/decompiler.ml b/src/coq/decompiler/decompiler.ml index 79463c5..df95ee5 100644 --- a/src/coq/decompiler/decompiler.ml +++ b/src/coq/decompiler/decompiler.ml @@ -166,10 +166,10 @@ let guard (b : bool) : unit option = if b then Some () else None (* Single dotted tactic. *) -let dot tac next = Some (Compose ([ tac ], [ next ])) +let dot sigma tac next : tactical state option = Some (sigma, Compose ([ tac ], [ next ])) (* Single tactic to finish proof. *) -let qed tac = Some (Compose ([ tac ], [])) +let qed sigma tac = Some (sigma, Compose ([ tac ], [])) (* Given the list of tactics and their corresponding string expressions, try to solve the goal (type of trm), @@ -189,14 +189,14 @@ let try_solve env sigma opts trm = with _ -> None (* Generates an apply tactic with implicit arguments if possible. *) -let apply_implicit env sigma trm = +let apply_implicit env sigma trm : tactical state option = try try_app trm >>= fun (f, args) -> try_name env f >>= fun name -> let s = String.concat " " [ "apply" ; name ] in let opt = parse_tac_str s in try_solve env sigma [ (opt, s) ] trm >>= fun tac -> - qed tac + qed sigma tac with _ -> None (* Performs the bulk of decompilation on a proof term. @@ -208,7 +208,7 @@ let rec first_pass (env : env) (sigma : Evd.evar_map) (get_hints : env -> Evd.evar_map -> constr -> (unit Proofview.tactic * string) list state) - (trm : constr) = + (trm : constr) : tactical state = (* Apply single reduction to terms that *might* be in eta expanded form. *) let trm = Reduction.whd_betaiota env trm in @@ -216,7 +216,7 @@ let rec first_pass let custom = try_custom_tacs env sigma get_hints hints trm in if Option.has_some custom then Option.get custom else - let def = Option.default (Compose ([ Apply (env, trm) ], [])) + let def = Option.default (sigma, Compose ([ Apply (env, trm) ], [])) (apply_implicit env sigma trm) in let choose f x = Option.default def (f x (env, sigma, get_hints)) in @@ -224,7 +224,8 @@ let rec first_pass (* "fun x => ..." -> "intro x." *) | Lambda (n, t, b) -> let (env', trm', names) = zoom_lambda_names env 0 trm in - Compose ([ Intros names ], [ first_pass env' sigma get_hints trm' ]) + let sigma, rest = first_pass env' sigma get_hints trm' in + sigma, Compose ([ Intros names ], [ rest ]) (* Match on well-known functions used in the proof. *) | App (f, args) -> choose (rewrite <|> induction <|> left <|> right <|> split @@ -237,14 +238,14 @@ let rec first_pass (* If successful, uses a custom tactic and decompiles subterms solving any generated subgoals. *) -and try_custom_tacs env sigma get_hints all_opts trm = +and try_custom_tacs env sigma get_hints all_opts trm : tactical state option = guard (not (isLambda trm)) >>= fun _ -> try let goal = (Typeops.infer env trm).uj_type in let goal_env env sigma g = let typ = EConstr.to_constr sigma (Goal.V82.abstract_type sigma g) in Zooming.zoom_product_type (Environ.reset_context env) typ in - let rec aux opts = + let rec aux opts : tactical state option = match opts with | [] -> None | (tac, expr) :: opts' -> @@ -253,7 +254,7 @@ and try_custom_tacs env sigma get_hints all_opts trm = let subgoals = List.map (goal_env env sigma) subgoals in if subgoals = [] then (* Goal solving *) - Some (Compose ([ Expr expr ], [])) + Some (sigma, Compose ([ Expr expr ], [])) else let new_env = fst (List.hd subgoals) in let sigma, same_env = Envutils.compare_envs env new_env sigma in @@ -261,6 +262,8 @@ and try_custom_tacs env sigma get_hints all_opts trm = then (* Both goal and context are unchanged *) aux opts' else (* Intermediate goal generating or context modifying tactic *) + (* NOTE: These produce a distinct sigma for each subgoal. So we + return the latest sigma (from compare_envs) here in the end. *) let subterms = List.map (fun (env', goal) -> (Typehofs.subterms_with_type env sigma goal trm, env')) subgoals in @@ -271,21 +274,22 @@ and try_custom_tacs env sigma get_hints all_opts trm = (* doesn't matter which subterm we found, it's a proof of the subgoal *) let subterms = List.map (fun (g, e) -> (list_snd g, e)) subterms in let proofs = List.map (fun ((sigma, (_, trm)), env') -> - first_pass env' sigma get_hints trm) subterms in - Some (Compose ([ Expr expr ], proofs)) + snd (first_pass env' sigma get_hints trm)) subterms in + Some (sigma, Compose ([ Expr expr ], proofs)) with _ -> aux opts' in aux all_opts with e -> (* raise e *) None (* Application of a equality eliminator. *) -and rewrite (f, args) (env, sigma, opts) : tactical option = +and rewrite (f, args) (env, sigma, opts) : tactical state option = let fx = mkApp (f, args) in dest_rewrite fx >>= fun rewr -> let sigma, goal = type_of env fx sigma in - dot (Rewrite (env, rewr.eq, rewr.left, goal)) (first_pass env sigma opts rewr.px) + let sigma, rest = first_pass env sigma opts rewr.px in + dot sigma (Rewrite (env, rewr.eq, rewr.left, goal)) rest (* Applying an eliminator for induction on a hypothesis in context. *) -and induction (f, args) (env, sigma, opts) : tactical option = +and induction (f, args) (env, sigma, opts) : tactical state option = guard (is_elim env f) >>= fun _ -> guard (not (is_rewrite f)) >>= fun _ -> let app = mkApp (f, args) in @@ -310,46 +314,50 @@ and induction (f, args) (env, sigma, opts) : tactical option = (* Compute bindings and goals for each case. *) let zooms = List.map (zoom_lambda_names env zoom_but) ind.cs in let names = List.map (fun (_, _, names) -> names) zooms in - let goals = List.map (fun (env, trm, _) -> first_pass env sigma opts trm) zooms in + let sigma, goals = map_state (fun (env, trm, _) sigma -> first_pass env sigma opts trm) zooms sigma in let ind = Compose ([ Induction (env, ind_var, names) ], goals) in - if reverts == [] then Some ind else dot (Revert reverts) ind + if reverts == [] then Some (sigma, ind) else dot sigma (Revert reverts) ind (* Choose left proof to construct or. *) -and left (f, args) (env, sigma, opts) : tactical option = +and left (f, args) (env, sigma, opts) : tactical state option = dest_or_introl (mkApp (f, args)) >>= fun args -> - dot (Left) (first_pass env sigma opts args.ltrm) + let sigma, rest = first_pass env sigma opts args.ltrm in + dot sigma (Left) rest (* Choose right proof to construct or. *) -and right (f, args) (env, sigma, opts) : tactical option = +and right (f, args) (env, sigma, opts) : tactical state option = dest_or_intror (mkApp (f, args)) >>= fun args -> - dot (Right) (first_pass env sigma opts args.rtrm) + let sigma, rest = first_pass env sigma opts args.rtrm in + dot sigma (Right) rest (* Branch two goals as arguments to conj. *) -and split (f, args) (env, sigma, opts) : tactical option = +and split (f, args) (env, sigma, opts) : tactical state option = dest_conj (mkApp (f, args)) >>= fun args -> - let lhs = first_pass env sigma opts args.ltrm in - let rhs = first_pass env sigma opts args.rtrm in - Some (Compose ([ Split ], [ lhs ; rhs ])) + let sigma, lhs = first_pass env sigma opts args.ltrm in + let sigma, rhs = first_pass env sigma opts args.rtrm in + Some (sigma, Compose ([ Split ], [ lhs ; rhs ])) (* Converts "apply eq_refl." into "reflexivity." *) -and reflexivity (f, args) _ : tactical option = +and reflexivity (f, args) (_, sigma, _) : tactical state option = dest_eq_refl_opt (mkApp (f, args)) >>= fun _ -> - qed Reflexivity + qed sigma Reflexivity (* Transform x = y to y = x. *) -and symmetry (f, args) (env, sigma, opts) : tactical option = +and symmetry (f, args) (env, sigma, opts) : tactical state option = guard (equal f eq_sym) >>= fun _ -> let sym = dest_eq_sym (mkApp (f, args)) in - dot (Symmetry) (first_pass env sigma opts sym.eq_proof) + let sigma, rest = first_pass env sigma opts sym.eq_proof in + dot sigma (Symmetry) rest (* Provide evidence for dependent pair. *) -and exists (f, args) (env, sigma, opts) : tactical option = +and exists (f, args) (env, sigma, opts) : tactical state option = guard (equal f Sigmautils.existT) >>= fun _ -> let exT = Sigmautils.dest_existT (mkApp (f, args)) in - dot (Exists (env, exT.index)) (first_pass env sigma opts exT.unpacked) + let sigma, rest = first_pass env sigma opts exT.unpacked in + dot sigma (Exists (env, exT.index)) rest (* Value must be a rewrite on a hypothesis in context. *) -and rewrite_in (_, valu, _, body) (env, sigma, opts) : tactical option = +and rewrite_in (_, valu, _, body) (env, sigma, opts) : tactical state option = let valu = Reduction.whd_betaiota env valu in try_app valu >>= fun (f, args) -> dest_rewrite (mkApp (f, args)) >>= fun rewr -> @@ -357,11 +365,11 @@ and rewrite_in (_, valu, _, body) (env, sigma, opts) : tactical option = guard (noccurn (idx + 1) body) >>= fun _ -> let n, t = rel_name_type (lookup_rel idx env) in let env' = push_local (n, t) env in - dot (RewriteIn (env, rewr.eq, rewr.px, rewr.left)) - (first_pass env' sigma opts body) + let sigma, rest = first_pass env' sigma opts body in + dot sigma (RewriteIn (env, rewr.eq, rewr.px, rewr.left)) rest (* Value must be an application with last argument in context. *) -and apply_in (n, valu, typ, body) (env, sigma, opts) : tactical option = +and apply_in (n, valu, typ, body) (env, sigma, opts) : tactical state option = let valu = Reduction.whd_betaiota env valu in try_app valu >>= fun (f, args) -> let len = Array.length args in @@ -377,28 +385,32 @@ and apply_in (n, valu, typ, body) (env, sigma, opts) : tactical option = try_app body >>= fun (f, args) -> try_rel f >>= fun i -> guard (i == 1) >>= fun _ -> - let args' = List.map (first_pass env' sigma opts) (Array.to_list args) in - Some (Compose ([ ApplyIn (env, prf, hyp) ], first_pass env' sigma opts f :: args')) + let sigma, f' = first_pass env' sigma opts f in + let sigma, args' = map_state (fun trm sigma -> first_pass env' sigma opts trm) + (Array.to_list args) sigma in + Some (sigma, Compose ([ ApplyIn (env, prf, hyp) ], f' :: args')) in (* all other cases *) - let default app_in (_, sigma) = dot (ApplyIn (env, prf, hyp)) - (first_pass env' sigma opts body) + let default app_in (_, sigma) = + let sigma, rest = first_pass env' sigma opts body in + dot sigma (ApplyIn (env, prf, hyp)) rest in (apply_binding <|> default) () (env', sigma) (* Last resort decompile let-in as a pose. *) -and pose (n, valu, t, body) (env, sigma, opts) : tactical option = +and pose (n, valu, t, body) (env, sigma, opts) : tactical state option = let n' = fresh_name env n in let env' = push_let_in (Name n', valu, t) env in - let decomp_body = first_pass env' sigma opts body in + let sigma, decomp_body = first_pass env' sigma opts body in (* If the binding is NEVER used, just skip this. *) - if noccurn 1 body then Some decomp_body - else dot (Pose (env, valu, n')) (decomp_body) - + if noccurn 1 body + then Some (sigma, decomp_body) + else dot sigma (Pose (env, valu, n')) (decomp_body) + (* Decompile a term into its equivalent tactic list. *) -let tac_from_term env sigma get_hints trm : tactical = +let tac_from_term env sigma get_hints trm : tactical state = first_pass env sigma get_hints trm - + (* Generate indentation space before bullet. *) let indent level = let spacing level = (level - 2) / 3 + 2 in diff --git a/src/coq/decompiler/decompiler.mli b/src/coq/decompiler/decompiler.mli index 5ebce7e..e8e12b3 100644 --- a/src/coq/decompiler/decompiler.mli +++ b/src/coq/decompiler/decompiler.mli @@ -44,7 +44,7 @@ val tac_from_term : env -> evar_map -> (env -> evar_map -> constr -> (unit Proofview.tactic * string) list state) -> constr -> - tactical + tactical state (* Given a decompiled Ltac script, return its string representation. *) val tac_to_string : evar_map -> tactical -> Pp.t From 4a709fa9dba62e51b9e621679c7ccf3b4d82fb8a Mon Sep 17 00:00:00 2001 From: RanDair Porter Date: Mon, 17 May 2021 13:38:26 -0700 Subject: [PATCH 04/39] Threading correct goal --- src/coq/decompiler/decompiler.ml | 163 ++++++++++++++++++++----------- 1 file changed, 106 insertions(+), 57 deletions(-) diff --git a/src/coq/decompiler/decompiler.ml b/src/coq/decompiler/decompiler.ml index df95ee5..386e910 100644 --- a/src/coq/decompiler/decompiler.ml +++ b/src/coq/decompiler/decompiler.ml @@ -41,16 +41,23 @@ let parse_tac_str (s : string) : unit Proofview.tactic = (* Run a coq tactic against a given goal, returning generated subgoals *) let run_tac env sigma (tac : unit Proofview.tactic) (goal : constr) - : Goal.goal list * Evd.evar_map = + : Goal.goal list state = let p = Proof.start sigma [(env, EConstr.of_constr goal)] in let (p', _) = Proof.run_tactic env tac p in let (subgoals, _, _, _, sigma) = Proof.proof p' in - subgoals, sigma + sigma, subgoals + +(* Convert a coq-generated subgoal into its context environment and goal type. *) +let get_context_goal env sigma (g : Goal.goal) : env * types = + let context_size = List.length (named_context (Goal.V82.env sigma g)) in + let abstr = EConstr.to_constr sigma (Goal.V82.abstract_type sigma g) in + Zooming.zoom_n_prod (reset_context env) context_size abstr + (* Returns true if the given tactic solves the goal. *) let solves env sigma (tac : unit Proofview.tactic) (goal : constr) : bool state = try - let subgoals, sigma = run_tac env sigma tac goal in + let sigma, subgoals = run_tac env sigma tac goal in sigma, subgoals = [] with _ -> sigma, false @@ -138,6 +145,12 @@ let show_tactic sigma tac : Pp.t = | Auto -> str "auto" | Expr s -> str s +(* Convert IR tactic to coq tactic by printing and parsing. *) +let coq_tac sigma t prefix = + let s = show_tactic sigma t in + let s' = Format.asprintf "%a" Pp.pp_with s in + parse_tac_str (prefix ^ s') + (* Option monad over function application. *) let try_app (trm : constr) : (constr * constr array) option = match kind trm with @@ -188,6 +201,22 @@ let try_solve env sigma opts trm = in aux sigma opts with _ -> None +(* Generate the new subgoals after applying a tactic to a goal. *) +let next_context_goals env sigma (t : tact) (goal : types) : (env * types) list state = + try + let sigma, subgoals = run_tac env sigma (coq_tac sigma t "") goal in + sigma, List.map (get_context_goal env sigma) subgoals + with e -> + Printing.debug_env env "Env"; + Printing.debug_term env goal "Goal"; + let s = show_tactic sigma t in + let s' = Format.asprintf "%a" Pp.pp_with s in + Printf.printf "Tactic: %s\n" s'; + let msg = Printexc.to_string e + and stack = Printexc.get_backtrace () in + Printf.eprintf "%s%s\n" msg stack; + raise e + (* Generates an apply tactic with implicit arguments if possible. *) let apply_implicit env sigma trm : tactical state option = try @@ -208,24 +237,28 @@ let rec first_pass (env : env) (sigma : Evd.evar_map) (get_hints : env -> Evd.evar_map -> constr -> (unit Proofview.tactic * string) list state) + (goal : types) (trm : constr) : tactical state = (* Apply single reduction to terms that *might* be in eta expanded form. *) let trm = Reduction.whd_betaiota env trm in let sigma, hints = get_hints env sigma trm in - let custom = try_custom_tacs env sigma get_hints hints trm in + let custom = try_custom_tacs env sigma get_hints hints goal trm in if Option.has_some custom then Option.get custom else let def = Option.default (sigma, Compose ([ Apply (env, trm) ], [])) (apply_implicit env sigma trm) in let choose f x = - Option.default def (f x (env, sigma, get_hints)) in + Option.default def (f x (env, sigma, get_hints, goal)) in match kind trm with (* "fun x => ..." -> "intro x." *) | Lambda (n, t, b) -> let (env', trm', names) = zoom_lambda_names env 0 trm in - let sigma, rest = first_pass env' sigma get_hints trm' in - sigma, Compose ([ Intros names ], [ rest ]) + let t = Intros names in + let sigma, next = next_context_goals env sigma t goal in + let _, goal' = List.hd next in + let sigma, rest = first_pass env' sigma get_hints goal' trm' in + sigma, Compose ([ t ], [ rest ]) (* Match on well-known functions used in the proof. *) | App (f, args) -> choose (rewrite <|> induction <|> left <|> right <|> split @@ -234,24 +267,35 @@ let rec first_pass | LetIn (n, valu, typ, body) -> choose (rewrite_in <|> apply_in <|> pose) (n, valu, typ, body) (* Remainder of body, simply apply it. *) - | _ -> def + | _ -> def + +(* Pass the updated goal to the next stage of decompilation. *) +and one_subgoal env sigma opts goal t trm = + let sigma, next = next_context_goals env sigma t goal in + let env', goal' = List.hd next in + let sigma, rest = first_pass env' sigma opts goal' trm in + sigma, Compose ([ t ], [ rest ]) + +(* Pass the updated goal to the next stages of decompilation. *) +and many_subgoals env sigma opts goal t trms = + let sigma, next = next_context_goals env sigma t goal in + let sigma, rests = + map2_state (fun (_, g) trm sigma -> first_pass env sigma opts g trm) next trms sigma in + sigma, Compose ([ t ], rests) (* If successful, uses a custom tactic and decompiles subterms solving any generated subgoals. *) -and try_custom_tacs env sigma get_hints all_opts trm : tactical state option = +and try_custom_tacs env sigma get_hints all_opts goal trm : tactical state option = guard (not (isLambda trm)) >>= fun _ -> try - let goal = (Typeops.infer env trm).uj_type in - let goal_env env sigma g = - let typ = EConstr.to_constr sigma (Goal.V82.abstract_type sigma g) in - Zooming.zoom_product_type (Environ.reset_context env) typ in + let goal = (Typeops.infer env trm).uj_type in let rec aux opts : tactical state option = match opts with | [] -> None | (tac, expr) :: opts' -> try - let subgoals, sigma = run_tac env sigma tac goal in - let subgoals = List.map (goal_env env sigma) subgoals in + let sigma, subgoals = run_tac env sigma tac goal in + let subgoals = List.map (get_context_goal env sigma) subgoals in if subgoals = [] then (* Goal solving *) Some (sigma, Compose ([ Expr expr ], [])) @@ -265,31 +309,30 @@ and try_custom_tacs env sigma get_hints all_opts trm : tactical state option = (* NOTE: These produce a distinct sigma for each subgoal. So we return the latest sigma (from compare_envs) here in the end. *) let subterms = List.map (fun (env', goal) -> - (Typehofs.subterms_with_type env sigma goal trm, env')) + (Typehofs.subterms_with_type env sigma goal trm, env', goal)) subgoals in (* could not find subterms to satisfy all subgoals? *) - if List.exists (fun x -> fst x = []) subterms + if List.exists (fun (x, _, _) -> x = []) subterms then aux opts' else - (* doesn't matter which subterm we found, it's a proof of the subgoal *) - let subterms = List.map (fun (g, e) -> (list_snd g, e)) subterms in - let proofs = List.map (fun ((sigma, (_, trm)), env') -> - snd (first_pass env' sigma get_hints trm)) subterms in + (* Pick the second subterm we found, since the first could be the entire term. *) + let subterms = List.map (fun (t, e, g) -> (list_snd t, e, g)) subterms in + let proofs = List.map (fun ((sigma, (_, trm)), env', goal') -> + snd (first_pass env' sigma get_hints goal' trm)) subterms in Some (sigma, Compose ([ Expr expr ], proofs)) with _ -> aux opts' in aux all_opts with e -> (* raise e *) None - + (* Application of a equality eliminator. *) -and rewrite (f, args) (env, sigma, opts) : tactical state option = +and rewrite (f, args) (env, sigma, opts, goal) : tactical state option = let fx = mkApp (f, args) in dest_rewrite fx >>= fun rewr -> - let sigma, goal = type_of env fx sigma in - let sigma, rest = first_pass env sigma opts rewr.px in - dot sigma (Rewrite (env, rewr.eq, rewr.left, goal)) rest + let t = Rewrite (env, rewr.eq, rewr.left, Some goal) in + Some (one_subgoal env sigma opts goal t rewr.px) (* Applying an eliminator for induction on a hypothesis in context. *) -and induction (f, args) (env, sigma, opts) : tactical state option = +and induction (f, args) (env, sigma, opts, goal) : tactical state option = guard (is_elim env f) >>= fun _ -> guard (not (is_rewrite f)) >>= fun _ -> let app = mkApp (f, args) in @@ -314,50 +357,55 @@ and induction (f, args) (env, sigma, opts) : tactical state option = (* Compute bindings and goals for each case. *) let zooms = List.map (zoom_lambda_names env zoom_but) ind.cs in let names = List.map (fun (_, _, names) -> names) zooms in - let sigma, goals = map_state (fun (env, trm, _) sigma -> first_pass env sigma opts trm) zooms sigma in - let ind = Compose ([ Induction (env, ind_var, names) ], goals) in - if reverts == [] then Some (sigma, ind) else dot sigma (Revert reverts) ind - + let finish goal = + let t = Induction (env, ind_var, names) in + let sigma, next = next_context_goals env sigma t goal in + let sigma, rests = map2_state (fun (_, trm, _) (env, goal') sigma -> + first_pass env sigma opts goal' trm) zooms next sigma in + Compose ([ t ], rests) in + if reverts == [] + then + Some (sigma, finish goal) + else + let t1 = Revert reverts in + let sigma, next = next_context_goals env sigma t1 goal in + let goal = snd (List.hd next) in + Some (sigma, Compose ([ t1 ], [ finish goal ])) + (* Choose left proof to construct or. *) -and left (f, args) (env, sigma, opts) : tactical state option = +and left (f, args) (env, sigma, opts, goal) : tactical state option = dest_or_introl (mkApp (f, args)) >>= fun args -> - let sigma, rest = first_pass env sigma opts args.ltrm in - dot sigma (Left) rest + Some (one_subgoal env sigma opts goal Left args.ltrm) (* Choose right proof to construct or. *) -and right (f, args) (env, sigma, opts) : tactical state option = +and right (f, args) (env, sigma, opts, goal) : tactical state option = dest_or_intror (mkApp (f, args)) >>= fun args -> - let sigma, rest = first_pass env sigma opts args.rtrm in - dot sigma (Right) rest + Some (one_subgoal env sigma opts goal Right args.rtrm) (* Branch two goals as arguments to conj. *) -and split (f, args) (env, sigma, opts) : tactical state option = +and split (f, args) (env, sigma, opts, goal) : tactical state option = dest_conj (mkApp (f, args)) >>= fun args -> - let sigma, lhs = first_pass env sigma opts args.ltrm in - let sigma, rhs = first_pass env sigma opts args.rtrm in - Some (sigma, Compose ([ Split ], [ lhs ; rhs ])) + Some (many_subgoals env sigma opts goal Split [ args.ltrm ; args.rtrm ]) (* Converts "apply eq_refl." into "reflexivity." *) -and reflexivity (f, args) (_, sigma, _) : tactical state option = +and reflexivity (f, args) (_, sigma, _, _) : tactical state option = dest_eq_refl_opt (mkApp (f, args)) >>= fun _ -> qed sigma Reflexivity (* Transform x = y to y = x. *) -and symmetry (f, args) (env, sigma, opts) : tactical state option = +and symmetry (f, args) (env, sigma, opts, goal) : tactical state option = guard (equal f eq_sym) >>= fun _ -> let sym = dest_eq_sym (mkApp (f, args)) in - let sigma, rest = first_pass env sigma opts sym.eq_proof in - dot sigma (Symmetry) rest + Some (one_subgoal env sigma opts goal Symmetry sym.eq_proof) (* Provide evidence for dependent pair. *) -and exists (f, args) (env, sigma, opts) : tactical state option = +and exists (f, args) (env, sigma, opts, goal) : tactical state option = guard (equal f Sigmautils.existT) >>= fun _ -> let exT = Sigmautils.dest_existT (mkApp (f, args)) in - let sigma, rest = first_pass env sigma opts exT.unpacked in - dot sigma (Exists (env, exT.index)) rest + Some (one_subgoal env sigma opts goal (Exists (env, exT.index)) exT.unpacked) (* Value must be a rewrite on a hypothesis in context. *) -and rewrite_in (_, valu, _, body) (env, sigma, opts) : tactical state option = +and rewrite_in (_, valu, _, body) (env, sigma, opts, goal) : tactical state option = let valu = Reduction.whd_betaiota env valu in try_app valu >>= fun (f, args) -> dest_rewrite (mkApp (f, args)) >>= fun rewr -> @@ -365,11 +413,11 @@ and rewrite_in (_, valu, _, body) (env, sigma, opts) : tactical state option = guard (noccurn (idx + 1) body) >>= fun _ -> let n, t = rel_name_type (lookup_rel idx env) in let env' = push_local (n, t) env in - let sigma, rest = first_pass env' sigma opts body in + let sigma, rest = first_pass env' sigma opts goal body in dot sigma (RewriteIn (env, rewr.eq, rewr.px, rewr.left)) rest (* Value must be an application with last argument in context. *) -and apply_in (n, valu, typ, body) (env, sigma, opts) : tactical state option = +and apply_in (n, valu, typ, body) (env, sigma, opts, goal) : tactical state option = let valu = Reduction.whd_betaiota env valu in try_app valu >>= fun (f, args) -> let len = Array.length args in @@ -385,23 +433,23 @@ and apply_in (n, valu, typ, body) (env, sigma, opts) : tactical state option = try_app body >>= fun (f, args) -> try_rel f >>= fun i -> guard (i == 1) >>= fun _ -> - let sigma, f' = first_pass env' sigma opts f in - let sigma, args' = map_state (fun trm sigma -> first_pass env' sigma opts trm) + let sigma, f' = first_pass env' sigma opts goal f in + let sigma, args' = map_state (fun trm sigma -> first_pass env' sigma opts goal trm) (Array.to_list args) sigma in Some (sigma, Compose ([ ApplyIn (env, prf, hyp) ], f' :: args')) in (* all other cases *) let default app_in (_, sigma) = - let sigma, rest = first_pass env' sigma opts body in + let sigma, rest = first_pass env' sigma opts goal body in dot sigma (ApplyIn (env, prf, hyp)) rest in (apply_binding <|> default) () (env', sigma) (* Last resort decompile let-in as a pose. *) -and pose (n, valu, t, body) (env, sigma, opts) : tactical state option = +and pose (n, valu, t, body) (env, sigma, opts, goal) : tactical state option = let n' = fresh_name env n in let env' = push_let_in (Name n', valu, t) env in - let sigma, decomp_body = first_pass env' sigma opts body in + let sigma, decomp_body = first_pass env' sigma opts goal body in (* If the binding is NEVER used, just skip this. *) if noccurn 1 body then Some (sigma, decomp_body) @@ -409,7 +457,8 @@ and pose (n, valu, t, body) (env, sigma, opts) : tactical state option = (* Decompile a term into its equivalent tactic list. *) let tac_from_term env sigma get_hints trm : tactical state = - first_pass env sigma get_hints trm + let sigma, goal = Inference.infer_type env sigma trm in + first_pass env sigma get_hints goal trm (* Generate indentation space before bullet. *) let indent level = From 672cddf07de2c5f04cc4d730e75475a97894cbf4 Mon Sep 17 00:00:00 2001 From: RanDair Porter Date: Mon, 24 May 2021 13:22:41 -0700 Subject: [PATCH 05/39] Decompiler errors default to using apply. --- src/coq/decompiler/decompiler.ml | 63 ++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/src/coq/decompiler/decompiler.ml b/src/coq/decompiler/decompiler.ml index 386e910..d6e857c 100644 --- a/src/coq/decompiler/decompiler.ml +++ b/src/coq/decompiler/decompiler.ml @@ -201,21 +201,17 @@ let try_solve env sigma opts trm = in aux sigma opts with _ -> None +exception RunTacExc of string * env * Evd.evar_map * types + (* Generate the new subgoals after applying a tactic to a goal. *) let next_context_goals env sigma (t : tact) (goal : types) : (env * types) list state = try let sigma, subgoals = run_tac env sigma (coq_tac sigma t "") goal in sigma, List.map (get_context_goal env sigma) subgoals with e -> - Printing.debug_env env "Env"; - Printing.debug_term env goal "Goal"; let s = show_tactic sigma t in let s' = Format.asprintf "%a" Pp.pp_with s in - Printf.printf "Tactic: %s\n" s'; - let msg = Printexc.to_string e - and stack = Printexc.get_backtrace () in - Printf.eprintf "%s%s\n" msg stack; - raise e + raise (RunTacExc (s', env, sigma, goal)) (* Generates an apply tactic with implicit arguments if possible. *) let apply_implicit env sigma trm : tactical state option = @@ -248,26 +244,37 @@ let rec first_pass else let def = Option.default (sigma, Compose ([ Apply (env, trm) ], [])) (apply_implicit env sigma trm) in - let choose f x = - Option.default def (f x (env, sigma, get_hints, goal)) in - match kind trm with - (* "fun x => ..." -> "intro x." *) - | Lambda (n, t, b) -> - let (env', trm', names) = zoom_lambda_names env 0 trm in - let t = Intros names in - let sigma, next = next_context_goals env sigma t goal in - let _, goal' = List.hd next in - let sigma, rest = first_pass env' sigma get_hints goal' trm' in - sigma, Compose ([ t ], [ rest ]) - (* Match on well-known functions used in the proof. *) - | App (f, args) -> - choose (rewrite <|> induction <|> left <|> right <|> split - <|> reflexivity <|> symmetry <|> exists) (f, args) - (* Hypothesis transformations or generation tactics. *) - | LetIn (n, valu, typ, body) -> - choose (rewrite_in <|> apply_in <|> pose) (n, valu, typ, body) - (* Remainder of body, simply apply it. *) - | _ -> def + try + let choose f x = + Option.default def (f x (env, sigma, get_hints, goal)) in + match kind trm with + (* "fun x => ..." -> "intro x." *) + | Lambda (n, t, b) -> + let (env', trm', names) = zoom_lambda_names env 0 trm in + let t = Intros names in + let sigma, next = next_context_goals env sigma t goal in + let _, goal' = List.hd next in + let sigma, rest = first_pass env' sigma get_hints goal' trm' in + sigma, Compose ([ t ], [ rest ]) + (* Match on well-known functions used in the proof. *) + | App (f, args) -> + choose (rewrite <|> induction <|> left <|> right <|> split + <|> reflexivity <|> symmetry <|> exists) (f, args) + (* Hypothesis transformations or generation tactics. *) + | LetIn (n, valu, typ, body) -> + choose (rewrite_in <|> apply_in <|> pose) (n, valu, typ, body) + (* Remainder of body, simply apply it. *) + | _ -> def + with + | (RunTacExc (s, env, sigma, goal)) -> + Feedback.msg_warning (str "Failed to execute: " ++ str s); + Feedback.msg_warning (str "on the goal: " ++ Printer.pr_constr_env env sigma goal); + def + | e -> + Feedback.msg_warning (str "Error occured while decompilin: "); + Feedback.msg_warning (str (Printexc.to_string e)); + def + (* Pass the updated goal to the next stage of decompilation. *) and one_subgoal env sigma opts goal t trm = @@ -459,7 +466,7 @@ and pose (n, valu, t, body) (env, sigma, opts, goal) : tactical state option = let tac_from_term env sigma get_hints trm : tactical state = let sigma, goal = Inference.infer_type env sigma trm in first_pass env sigma get_hints goal trm - + (* Generate indentation space before bullet. *) let indent level = let spacing level = (level - 2) / 3 + 2 in From 9e853059f0be095956267392b4ab608c614baae1 Mon Sep 17 00:00:00 2001 From: RanDair Porter Date: Tue, 22 Jun 2021 11:25:18 -0700 Subject: [PATCH 06/39] Passing list of previously used tactics into get_hints --- src/coq/decompiler/decompiler.ml | 130 +++++++++++++++++------------- src/coq/decompiler/decompiler.mli | 3 +- 2 files changed, 75 insertions(+), 58 deletions(-) diff --git a/src/coq/decompiler/decompiler.ml b/src/coq/decompiler/decompiler.ml index d6e857c..9e26d57 100644 --- a/src/coq/decompiler/decompiler.ml +++ b/src/coq/decompiler/decompiler.ml @@ -101,7 +101,7 @@ type tactical = stored in reverse order to push in constant time. *) | Compose of tact list * (tactical list) -(* Return the string representation of a single tactic. *) +(* Return the Pp.t representation of a single tactic. *) let show_tactic sigma tac : Pp.t = let prnt e = Printer.pr_constr_env e sigma in match tac with @@ -145,11 +145,14 @@ let show_tactic sigma tac : Pp.t = | Auto -> str "auto" | Expr s -> str s +(* Return the string representation of a single tactic. *) +let show_tactic_string sigma t = + let s = show_tactic sigma t in + Format.asprintf "%a" Pp.pp_with s + (* Convert IR tactic to coq tactic by printing and parsing. *) let coq_tac sigma t prefix = - let s = show_tactic sigma t in - let s' = Format.asprintf "%a" Pp.pp_with s in - parse_tac_str (prefix ^ s') + parse_tac_str (prefix ^ show_tactic_string sigma t) (* Option monad over function application. *) let try_app (trm : constr) : (constr * constr array) option = @@ -232,21 +235,22 @@ let apply_implicit env sigma trm : tactical state option = let rec first_pass (env : env) (sigma : Evd.evar_map) - (get_hints : env -> Evd.evar_map -> constr -> (unit Proofview.tactic * string) list state) + (get_hints : env -> Evd.evar_map -> string list -> constr -> + (unit Proofview.tactic * string) list state) + (prev : string list) (goal : types) (trm : constr) : tactical state = (* Apply single reduction to terms that *might* be in eta expanded form. *) let trm = Reduction.whd_betaiota env trm in - let sigma, hints = get_hints env sigma trm in - let custom = try_custom_tacs env sigma get_hints hints goal trm in + let custom = try_custom_tacs env sigma get_hints prev goal trm in if Option.has_some custom then Option.get custom else let def = Option.default (sigma, Compose ([ Apply (env, trm) ], [])) (apply_implicit env sigma trm) in try let choose f x = - Option.default def (f x (env, sigma, get_hints, goal)) in + Option.default def (f x (env, sigma, get_hints, prev, goal)) in match kind trm with (* "fun x => ..." -> "intro x." *) | Lambda (n, t, b) -> @@ -254,7 +258,7 @@ let rec first_pass let t = Intros names in let sigma, next = next_context_goals env sigma t goal in let _, goal' = List.hd next in - let sigma, rest = first_pass env' sigma get_hints goal' trm' in + let sigma, rest = first_pass env' sigma get_hints (show_tactic_string sigma t :: prev) goal' trm' in sigma, Compose ([ t ], [ rest ]) (* Match on well-known functions used in the proof. *) | App (f, args) -> @@ -277,24 +281,26 @@ let rec first_pass (* Pass the updated goal to the next stage of decompilation. *) -and one_subgoal env sigma opts goal t trm = +and one_subgoal env sigma opts prev goal t trm = let sigma, next = next_context_goals env sigma t goal in let env', goal' = List.hd next in - let sigma, rest = first_pass env' sigma opts goal' trm in + let sigma, rest = first_pass env' sigma opts (show_tactic_string sigma t :: prev) goal' trm in sigma, Compose ([ t ], [ rest ]) (* Pass the updated goal to the next stages of decompilation. *) -and many_subgoals env sigma opts goal t trms = +and many_subgoals env sigma opts prev goal t trms = let sigma, next = next_context_goals env sigma t goal in let sigma, rests = - map2_state (fun (_, g) trm sigma -> first_pass env sigma opts g trm) next trms sigma in + map2_state (fun (_, g) trm sigma -> + first_pass env sigma opts (show_tactic_string sigma t :: prev) g trm) next trms sigma in sigma, Compose ([ t ], rests) - + (* If successful, uses a custom tactic and decompiles subterms solving any generated subgoals. *) -and try_custom_tacs env sigma get_hints all_opts goal trm : tactical state option = +and try_custom_tacs env sigma get_hints prev goal trm : tactical state option = guard (not (isLambda trm)) >>= fun _ -> - try + try + let sigma, hints = get_hints env sigma prev trm in let goal = (Typeops.infer env trm).uj_type in let rec aux opts : tactical state option = match opts with @@ -323,23 +329,25 @@ and try_custom_tacs env sigma get_hints all_opts goal trm : tactical state optio then aux opts' else (* Pick the second subterm we found, since the first could be the entire term. *) + let t = Expr expr in let subterms = List.map (fun (t, e, g) -> (list_snd t, e, g)) subterms in let proofs = List.map (fun ((sigma, (_, trm)), env', goal') -> - snd (first_pass env' sigma get_hints goal' trm)) subterms in - Some (sigma, Compose ([ Expr expr ], proofs)) + snd (first_pass env' sigma get_hints (show_tactic_string sigma t :: prev) + goal' trm)) subterms in + Some (sigma, Compose ([ t ], proofs)) with _ -> aux opts' - in aux all_opts + in aux hints with e -> (* raise e *) None (* Application of a equality eliminator. *) -and rewrite (f, args) (env, sigma, opts, goal) : tactical state option = +and rewrite (f, args) (env, sigma, opts, prev, goal) : tactical state option = let fx = mkApp (f, args) in dest_rewrite fx >>= fun rewr -> let t = Rewrite (env, rewr.eq, rewr.left, Some goal) in - Some (one_subgoal env sigma opts goal t rewr.px) + Some (one_subgoal env sigma opts prev goal t rewr.px) (* Applying an eliminator for induction on a hypothesis in context. *) -and induction (f, args) (env, sigma, opts, goal) : tactical state option = +and induction (f, args) (env, sigma, opts, prev, goal) : tactical state option = guard (is_elim env f) >>= fun _ -> guard (not (is_rewrite f)) >>= fun _ -> let app = mkApp (f, args) in @@ -364,67 +372,69 @@ and induction (f, args) (env, sigma, opts, goal) : tactical state option = (* Compute bindings and goals for each case. *) let zooms = List.map (zoom_lambda_names env zoom_but) ind.cs in let names = List.map (fun (_, _, names) -> names) zooms in - let finish goal = + let finish goal reverts = let t = Induction (env, ind_var, names) in let sigma, next = next_context_goals env sigma t goal in let sigma, rests = map2_state (fun (_, trm, _) (env, goal') sigma -> - first_pass env sigma opts goal' trm) zooms next sigma in + first_pass env sigma opts (reverts @ show_tactic_string sigma t :: prev) + goal' trm) zooms next sigma in Compose ([ t ], rests) in if reverts == [] then - Some (sigma, finish goal) + Some (sigma, finish goal []) else let t1 = Revert reverts in let sigma, next = next_context_goals env sigma t1 goal in let goal = snd (List.hd next) in - Some (sigma, Compose ([ t1 ], [ finish goal ])) + Some (sigma, Compose ([ t1 ], [ finish goal [show_tactic_string sigma t1] ])) (* Choose left proof to construct or. *) -and left (f, args) (env, sigma, opts, goal) : tactical state option = +and left (f, args) (env, sigma, opts, prev, goal) : tactical state option = dest_or_introl (mkApp (f, args)) >>= fun args -> - Some (one_subgoal env sigma opts goal Left args.ltrm) + Some (one_subgoal env sigma opts prev goal Left args.ltrm) (* Choose right proof to construct or. *) -and right (f, args) (env, sigma, opts, goal) : tactical state option = +and right (f, args) (env, sigma, opts, prev, goal) : tactical state option = dest_or_intror (mkApp (f, args)) >>= fun args -> - Some (one_subgoal env sigma opts goal Right args.rtrm) + Some (one_subgoal env sigma opts prev goal Right args.rtrm) (* Branch two goals as arguments to conj. *) -and split (f, args) (env, sigma, opts, goal) : tactical state option = +and split (f, args) (env, sigma, opts, prev, goal) : tactical state option = dest_conj (mkApp (f, args)) >>= fun args -> - Some (many_subgoals env sigma opts goal Split [ args.ltrm ; args.rtrm ]) + Some (many_subgoals env sigma opts prev goal Split [ args.ltrm ; args.rtrm ]) (* Converts "apply eq_refl." into "reflexivity." *) -and reflexivity (f, args) (_, sigma, _, _) : tactical state option = +and reflexivity (f, args) (_, sigma, _, _, _) : tactical state option = dest_eq_refl_opt (mkApp (f, args)) >>= fun _ -> qed sigma Reflexivity (* Transform x = y to y = x. *) -and symmetry (f, args) (env, sigma, opts, goal) : tactical state option = +and symmetry (f, args) (env, sigma, opts, prev, goal) : tactical state option = guard (equal f eq_sym) >>= fun _ -> let sym = dest_eq_sym (mkApp (f, args)) in - Some (one_subgoal env sigma opts goal Symmetry sym.eq_proof) + Some (one_subgoal env sigma opts prev goal Symmetry sym.eq_proof) (* Provide evidence for dependent pair. *) -and exists (f, args) (env, sigma, opts, goal) : tactical state option = +and exists (f, args) (env, sigma, opts, prev, goal) : tactical state option = guard (equal f Sigmautils.existT) >>= fun _ -> let exT = Sigmautils.dest_existT (mkApp (f, args)) in - Some (one_subgoal env sigma opts goal (Exists (env, exT.index)) exT.unpacked) + Some (one_subgoal env sigma opts prev goal (Exists (env, exT.index)) exT.unpacked) (* Value must be a rewrite on a hypothesis in context. *) -and rewrite_in (_, valu, _, body) (env, sigma, opts, goal) : tactical state option = +and rewrite_in (_, valu, _, body) (env, sigma, opts, prev, goal) : tactical state option = let valu = Reduction.whd_betaiota env valu in try_app valu >>= fun (f, args) -> dest_rewrite (mkApp (f, args)) >>= fun rewr -> try_rel rewr.px >>= fun idx -> guard (noccurn (idx + 1) body) >>= fun _ -> - let n, t = rel_name_type (lookup_rel idx env) in - let env' = push_local (n, t) env in - let sigma, rest = first_pass env' sigma opts goal body in - dot sigma (RewriteIn (env, rewr.eq, rewr.px, rewr.left)) rest + let t = RewriteIn (env, rewr.eq, rewr.px, rewr.left) in + let n, typ = rel_name_type (lookup_rel idx env) in + let env' = push_local (n, typ) env in + let sigma, rest = first_pass env' sigma opts (show_tactic_string sigma t :: prev) goal body in + dot sigma t rest (* Value must be an application with last argument in context. *) -and apply_in (n, valu, typ, body) (env, sigma, opts, goal) : tactical state option = +and apply_in (n, valu, _, body) (env, sigma, opts, prev, goal) : tactical state option = let valu = Reduction.whd_betaiota env valu in try_app valu >>= fun (f, args) -> let len = Array.length args in @@ -432,40 +442,46 @@ and apply_in (n, valu, typ, body) (env, sigma, opts, goal) : tactical state opti try_rel hyp >>= fun idx -> (* let H' := F H *) guard (noccurn (idx + 1) body) >>= fun _ -> (* H does not occur in body *) guard (not (noccurn 1 body)) >>= fun _ -> (* new binding DOES occur *) - let n, t = rel_name_type (lookup_rel idx env) in (* "H" *) - let env' = push_local (n, t) env in (* change type of "H" *) + let n, typ = rel_name_type (lookup_rel idx env) in (* "H" *) + let env' = push_local (n, typ) env in (* change type of "H" *) let prf = mkApp (f, Array.sub args 0 (len - 1)) in - (* let H2 := f H1 := H2 ... *) + let t = ApplyIn (env, prf, hyp) in + (* let A := f B C D ... in A *) let apply_binding app_in (_, sigma) = try_app body >>= fun (f, args) -> try_rel f >>= fun i -> guard (i == 1) >>= fun _ -> - let sigma, f' = first_pass env' sigma opts goal f in - let sigma, args' = map_state (fun trm sigma -> first_pass env' sigma opts goal trm) + let sigma, f' = first_pass env' sigma opts (show_tactic_string sigma t :: prev) goal f in + let sigma, args' = map_state (fun trm sigma -> + first_pass env' sigma opts (show_tactic_string sigma t :: prev) goal trm) (Array.to_list args) sigma in - Some (sigma, Compose ([ ApplyIn (env, prf, hyp) ], f' :: args')) + Some (sigma, Compose ([ t ], f' :: args')) in (* all other cases *) let default app_in (_, sigma) = - let sigma, rest = first_pass env' sigma opts goal body in - dot sigma (ApplyIn (env, prf, hyp)) rest + let sigma, rest = first_pass env' sigma opts (show_tactic_string sigma t :: prev) goal body in + dot sigma t rest in (apply_binding <|> default) () (env', sigma) (* Last resort decompile let-in as a pose. *) -and pose (n, valu, t, body) (env, sigma, opts, goal) : tactical state option = +and pose (n, valu, typ, body) (env, sigma, opts, prev, goal) : tactical state option = let n' = fresh_name env n in - let env' = push_let_in (Name n', valu, t) env in - let sigma, decomp_body = first_pass env' sigma opts goal body in + let env' = push_let_in (Name n', valu, typ) env in (* If the binding is NEVER used, just skip this. *) if noccurn 1 body - then Some (sigma, decomp_body) - else dot sigma (Pose (env, valu, n')) (decomp_body) + then + let sigma, decomp_body = first_pass env' sigma opts prev goal body in + Some (sigma, decomp_body) + else + let t = Pose (env, valu, n') in + let sigma, decomp_body = first_pass env' sigma opts (show_tactic_string sigma t :: prev) goal body in + dot sigma t (decomp_body) (* Decompile a term into its equivalent tactic list. *) let tac_from_term env sigma get_hints trm : tactical state = let sigma, goal = Inference.infer_type env sigma trm in - first_pass env sigma get_hints goal trm + first_pass env sigma get_hints [] goal trm (* Generate indentation space before bullet. *) let indent level = diff --git a/src/coq/decompiler/decompiler.mli b/src/coq/decompiler/decompiler.mli index e8e12b3..8b721cc 100644 --- a/src/coq/decompiler/decompiler.mli +++ b/src/coq/decompiler/decompiler.mli @@ -42,7 +42,8 @@ val parse_tac_str : string -> unit Proofview.tactic Each proofview tactic in the list must be paired with their string representation. *) val tac_from_term : env -> evar_map -> - (env -> evar_map -> constr -> (unit Proofview.tactic * string) list state) -> + (env -> evar_map -> string list -> constr -> + (unit Proofview.tactic * string) list state) -> constr -> tactical state From 4838908702dfe40d8e00ece54275c3fc84a8ac9d Mon Sep 17 00:00:00 2001 From: efirst Date: Tue, 7 Sep 2021 16:01:01 -0400 Subject: [PATCH 07/39] base infrastructure change with submodules added in git --- .gitmodules | 6 + Makefile | 802 +++++++++++++++++++++++++++++++++++++++++++++++ Makefile.local | 1 + _CoqProject | 2 +- coq-serapi | 1 + pyml | 1 + src/plib.mlpack | 4 +- src/plibrary.ml4 | 53 ++++ theories/Plib.v | 5 + 9 files changed, 873 insertions(+), 2 deletions(-) create mode 100644 .gitmodules create mode 100644 Makefile create mode 100644 Makefile.local create mode 160000 coq-serapi create mode 160000 pyml diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..57f1151 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "pyml"] + path = pyml + url = https://github.com/thierry-martinez/pyml +[submodule "coq-serapi"] + path = coq-serapi + url = https://github.com/ejgallego/coq-serapi diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3d05fd8 --- /dev/null +++ b/Makefile @@ -0,0 +1,802 @@ +############################################################################### +## v # The Coq Proof Assistant ## +## /dev/null 2>/dev/null; echo $$?)) +STDTIME?=command time -f $(TIMEFMT) +else +ifeq (0,$(shell gtime -f $(TIMEFMT) true >/dev/null 2>/dev/null; echo $$?)) +STDTIME?=gtime -f $(TIMEFMT) +else +STDTIME?=command time +endif +endif +else +STDTIME?=command time -f $(TIMEFMT) +endif + +# Coq binaries +COQC ?= "$(COQBIN)coqc" +COQTOP ?= "$(COQBIN)coqtop" +COQCHK ?= "$(COQBIN)coqchk" +COQDEP ?= "$(COQBIN)coqdep" +COQDOC ?= "$(COQBIN)coqdoc" +COQMKFILE ?= "$(COQBIN)coq_makefile" + +# Timing scripts +COQMAKE_ONE_TIME_FILE ?= "$(COQLIB)/tools/make-one-time-file.py" +COQMAKE_BOTH_TIME_FILES ?= "$(COQLIB)/tools/make-both-time-files.py" +COQMAKE_BOTH_SINGLE_TIMING_FILES ?= "$(COQLIB)/tools/make-both-single-timing-files.py" +BEFORE ?= +AFTER ?= + +# FIXME this should be generated by Coq (modules already linked by Coq) +CAMLDONTLINK=camlp5.gramlib,unix,str + +# OCaml binaries +CAMLC ?= "$(OCAMLFIND)" ocamlc -c +CAMLOPTC ?= "$(OCAMLFIND)" opt -c +CAMLLINK ?= "$(OCAMLFIND)" ocamlc -linkpkg -dontlink $(CAMLDONTLINK) +CAMLOPTLINK ?= "$(OCAMLFIND)" opt -linkpkg -dontlink $(CAMLDONTLINK) +CAMLDOC ?= "$(OCAMLFIND)" ocamldoc +CAMLDEP ?= "$(OCAMLFIND)" ocamldep -slash -ml-synonym .ml4 -ml-synonym .mlpack + +# DESTDIR is prepended to all installation paths +DESTDIR ?= + +# Debug builds, typically -g to OCaml, -debug to Coq. +CAMLDEBUG ?= +COQDEBUG ?= + +# Extra packages to be linked in (as in findlib -package) +CAMLPKGS ?= + +# Option for making timing files +TIMING?= +# Option for changing sorting of timing output file +TIMING_SORT_BY ?= auto +# Output file names for timed builds +TIME_OF_BUILD_FILE ?= time-of-build.log +TIME_OF_BUILD_BEFORE_FILE ?= time-of-build-before.log +TIME_OF_BUILD_AFTER_FILE ?= time-of-build-after.log +TIME_OF_PRETTY_BUILD_FILE ?= time-of-build-pretty.log +TIME_OF_PRETTY_BOTH_BUILD_FILE ?= time-of-build-both.log +TIME_OF_PRETTY_BUILD_EXTRA_FILES ?= - # also output to the command line + +########## End of parameters ################################################## +# What follows may be relevant to you only if you need to +# extend this Makefile. If so, look for 'Extension point' here and +# put in Makefile.local double colon rules accordingly. +# E.g. to perform some work after the all target completes you can write +# +# post-all:: +# echo "All done!" +# +# in Makefile.local +# +############################################################################### + + + + +# Flags ####################################################################### +# +# We define a bunch of variables combining the parameters. +# To add additional flags to coq, coqchk or coqdoc, set the +# {COQ,COQCHK,COQDOC}EXTRAFLAGS variable to whatever you want to add. +# To overwrite the default choice and set your own flags entirely, set the +# {COQ,COQCHK,COQDOC}FLAGS variable. + +SHOW := $(if $(VERBOSE),@true "",@echo "") +HIDE := $(if $(VERBOSE),,@) + +TIMER=$(if $(TIMED), $(STDTIME), $(TIMECMD)) + +OPT?= + +# The DYNOBJ and DYNLIB variables are used by "coqdep -dyndep var" in .v.d +ifeq '$(OPT)' '-byte' +USEBYTE:=true +DYNOBJ:=.cma +DYNLIB:=.cma +else +USEBYTE:= +DYNOBJ:=.cmxs +DYNLIB:=.cmxs +endif + +# these variables are meant to be overriden if you want to add *extra* flags +COQEXTRAFLAGS?= +COQCHKEXTRAFLAGS?= +COQDOCEXTRAFLAGS?= + +# these flags do NOT contain the libraries, to make them easier to overwrite +COQFLAGS?=-q $(OPT) $(OTHERFLAGS) $(COQEXTRAFLAGS) +COQCHKFLAGS?=-silent -o $(COQCHKEXTRAFLAGS) +COQDOCFLAGS?=-interpolate -utf8 $(COQDOCEXTRAFLAGS) + +COQDOCLIBS?=$(COQLIBS_NOML) + +# The version of Coq being run and the version of coq_makefile that +# generated this makefile +COQ_VERSION:=$(shell $(COQC) --print-version | cut -d " " -f 1) +COQMAKEFILE_VERSION:=8.9.1 + +COQSRCLIBS?= $(foreach d,$(COQ_SRC_SUBDIRS), -I "$(COQLIB)$(d)") + +CAMLFLAGS+=$(OCAMLLIBS) $(COQSRCLIBS) -I $(CAMLP5LIB) + +# ocamldoc fails with unknown argument otherwise +CAMLDOCFLAGS=$(filter-out -annot, $(filter-out -bin-annot, $(CAMLFLAGS))) + +# FIXME This should be generated by Coq +GRAMMARS:=grammar.cma +CAMLP5EXTEND=pa_extend.cmo q_MLast.cmo pa_macro.cmo + +CAMLLIB:=$(shell "$(OCAMLFIND)" printconf stdlib 2> /dev/null) +ifeq (,$(CAMLLIB)) +PP=$(error "Cannot find the 'ocamlfind' binary used to build Coq ($(OCAMLFIND)). Pre-compiled binary packages of Coq do not support compiling plugins this way. Please download the sources of Coq and run the Windows build script.") +else +PP:=-pp '$(CAMLP5O) -I $(CAMLLIB) -I "$(COQLIB)/grammar" $(CAMLP5EXTEND) $(GRAMMARS) $(CAMLP5OPTIONS) -impl' +endif + +ifneq (,$(TIMING)) +TIMING_ARG=-time +ifeq (after,$(TIMING)) +TIMING_EXT=after-timing +else +ifeq (before,$(TIMING)) +TIMING_EXT=before-timing +else +TIMING_EXT=timing +endif +endif +else +TIMING_ARG= +endif + +# Retro compatibility (DESTDIR is standard on Unix, DSTROOT is not) +ifdef DSTROOT +DESTDIR := $(DSTROOT) +endif + +concat_path = $(if $(1),$(1)/$(if $(COQMF_WINDRIVE),$(subst $(COQMF_WINDRIVE),/,$(2)),$(2)),$(2)) + +COQLIBINSTALL = $(call concat_path,$(DESTDIR),$(COQLIB)user-contrib) +COQDOCINSTALL = $(call concat_path,$(DESTDIR),$(DOCDIR)user-contrib) +COQTOPINSTALL = $(call concat_path,$(DESTDIR),$(COQLIB)toploop) + +# Files ####################################################################### +# +# We here define a bunch of variables about the files being part of the +# Coq project in order to ease the writing of build target and build rules + +VDFILE := .coqdeps + +ALLSRCFILES := \ + $(ML4FILES) \ + $(MLFILES) \ + $(MLPACKFILES) \ + $(MLLIBFILES) \ + $(MLIFILES) + +# helpers +vo_to_obj = $(addsuffix .o,\ + $(filter-out Warning: Error:,\ + $(shell $(COQTOP) -q -noinit -batch -quiet -print-mod-uid $(1)))) +strip_dotslash = $(patsubst ./%,%,$(1)) +VO = vo + +VOFILES = $(VFILES:.v=.$(VO)) +GLOBFILES = $(VFILES:.v=.glob) +HTMLFILES = $(VFILES:.v=.html) +GHTMLFILES = $(VFILES:.v=.g.html) +BEAUTYFILES = $(addsuffix .beautified,$(VFILES)) +TEXFILES = $(VFILES:.v=.tex) +GTEXFILES = $(VFILES:.v=.g.tex) +CMOFILES = \ + $(ML4FILES:.ml4=.cmo) \ + $(MLFILES:.ml=.cmo) \ + $(MLPACKFILES:.mlpack=.cmo) +CMXFILES = $(CMOFILES:.cmo=.cmx) +OFILES = $(CMXFILES:.cmx=.o) +CMAFILES = $(MLLIBFILES:.mllib=.cma) $(MLPACKFILES:.mlpack=.cma) +CMXAFILES = $(CMAFILES:.cma=.cmxa) +CMIFILES = \ + $(CMOFILES:.cmo=.cmi) \ + $(MLIFILES:.mli=.cmi) +# the /if/ is because old _CoqProject did not list a .ml(pack|lib) but just +# a .ml4 file +CMXSFILES = \ + $(MLPACKFILES:.mlpack=.cmxs) \ + $(CMXAFILES:.cmxa=.cmxs) \ + $(if $(MLPACKFILES)$(CMXAFILES),,\ + $(ML4FILES:.ml4=.cmxs) $(MLFILES:.ml=.cmxs)) + +# files that are packed into a plugin (no extension) +PACKEDFILES = \ + $(call strip_dotslash, \ + $(foreach lib, \ + $(call strip_dotslash, \ + $(MLPACKFILES:.mlpack=_MLPACK_DEPENDENCIES)),$($(lib)))) +# files that are archived into a .cma (mllib) +LIBEDFILES = \ + $(call strip_dotslash, \ + $(foreach lib, \ + $(call strip_dotslash, \ + $(MLLIBFILES:.mllib=_MLLIB_DEPENDENCIES)),$($(lib)))) +CMIFILESTOINSTALL = $(filter-out $(addsuffix .cmi,$(PACKEDFILES)),$(CMIFILES)) +CMOFILESTOINSTALL = $(filter-out $(addsuffix .cmo,$(PACKEDFILES)),$(CMOFILES)) +OBJFILES = $(call vo_to_obj,$(VOFILES)) +ALLNATIVEFILES = \ + $(OBJFILES:.o=.cmi) \ + $(OBJFILES:.o=.cmx) \ + $(OBJFILES:.o=.cmxs) +# trick: wildcard filters out non-existing files, so that `install` doesn't show +# warnings and `clean` doesn't pass to rm a list of files that is too long for +# the shell. +NATIVEFILES = $(wildcard $(ALLNATIVEFILES)) +FILESTOINSTALL = \ + $(VOFILES) \ + $(VFILES) \ + $(GLOBFILES) \ + $(NATIVEFILES) \ + $(CMIFILESTOINSTALL) +BYTEFILESTOINSTALL = \ + $(CMOFILESTOINSTALL) \ + $(CMAFILES) +ifeq '$(HASNATDYNLINK)' 'true' +DO_NATDYNLINK = yes +FILESTOINSTALL += $(CMXSFILES) $(CMXAFILES) $(CMOFILESTOINSTALL:.cmo=.cmx) +else +DO_NATDYNLINK = +endif + +ALLDFILES = $(addsuffix .d,$(ALLSRCFILES) $(VDFILE)) + +# Compilation targets ######################################################### + +all: + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" pre-all + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" real-all + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" post-all +.PHONY: all + +all.timing.diff: + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" pre-all + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" real-all.timing.diff TIME_OF_PRETTY_BUILD_EXTRA_FILES="" + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" post-all +.PHONY: all.timing.diff + +make-pretty-timed-before:: TIME_OF_BUILD_FILE=$(TIME_OF_BUILD_BEFORE_FILE) +make-pretty-timed-after:: TIME_OF_BUILD_FILE=$(TIME_OF_BUILD_AFTER_FILE) +make-pretty-timed make-pretty-timed-before make-pretty-timed-after:: + $(HIDE)rm -f pretty-timed-success.ok + $(HIDE)($(MAKE) --no-print-directory -f "$(PARENT)" $(TGTS) TIMED=1 2>&1 && touch pretty-timed-success.ok) | tee -a $(TIME_OF_BUILD_FILE) + $(HIDE)rm pretty-timed-success.ok # must not be -f; must fail if the touch failed +print-pretty-timed:: + $(HIDE)$(COQMAKE_ONE_TIME_FILE) $(TIME_OF_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES) +print-pretty-timed-diff:: + $(HIDE)$(COQMAKE_BOTH_TIME_FILES) --sort-by=$(TIMING_SORT_BY) $(TIME_OF_BUILD_AFTER_FILE) $(TIME_OF_BUILD_BEFORE_FILE) $(TIME_OF_PRETTY_BOTH_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES) +ifeq (,$(BEFORE)) +print-pretty-single-time-diff:: + @echo 'Error: Usage: $(MAKE) print-pretty-single-time-diff AFTER=path/to/file.v.after-timing BEFORE=path/to/file.v.before-timing' + $(HIDE)false +else +ifeq (,$(AFTER)) +print-pretty-single-time-diff:: + @echo 'Error: Usage: $(MAKE) print-pretty-single-time-diff AFTER=path/to/file.v.after-timing BEFORE=path/to/file.v.before-timing' + $(HIDE)false +else +print-pretty-single-time-diff:: + $(HIDE)$(COQMAKE_BOTH_SINGLE_TIMING_FILES) --sort-by=$(TIMING_SORT_BY) $(AFTER) $(BEFORE) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES) +endif +endif +pretty-timed: + $(HIDE)$(MAKE) --no-print-directory -f "$(PARENT)" make-pretty-timed + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" print-pretty-timed +.PHONY: pretty-timed make-pretty-timed make-pretty-timed-before make-pretty-timed-after print-pretty-timed print-pretty-timed-diff print-pretty-single-time-diff + +# Extension points for actions to be performed before/after the all target +pre-all:: + @# Extension point + $(HIDE)if [ "$(COQMAKEFILE_VERSION)" != "$(COQ_VERSION)" ]; then\ + echo "W: This Makefile was generated by Coq $(COQMAKEFILE_VERSION)";\ + echo "W: while the current Coq version is $(COQ_VERSION)";\ + fi +.PHONY: pre-all + +post-all:: + @# Extension point +.PHONY: post-all + +real-all: $(VOFILES) $(if $(USEBYTE),bytefiles,optfiles) +.PHONY: real-all + +real-all.timing.diff: $(VOFILES:.vo=.v.timing.diff) +.PHONY: real-all.timing.diff + +bytefiles: $(CMOFILES) $(CMAFILES) +.PHONY: bytefiles + +optfiles: $(if $(DO_NATDYNLINK),$(CMXSFILES)) +.PHONY: optfiles + +# FIXME, see Ralf's bugreport +quick: $(VOFILES:.vo=.vio) +.PHONY: quick + +vio2vo: + $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) \ + -schedule-vio2vo $(J) $(VOFILES:%.vo=%.vio) +.PHONY: vio2vo + +quick2vo: + $(HIDE)make -j $(J) quick + $(HIDE)VIOFILES=$$(for vofile in $(VOFILES); do \ + viofile="$$(echo "$$vofile" | sed "s/\.vo$$/.vio/")"; \ + if [ "$$vofile" -ot "$$viofile" -o ! -e "$$vofile" ]; then printf "$$viofile "; fi; \ + done); \ + echo "VIO2VO: $$VIOFILES"; \ + if [ -n "$$VIOFILES" ]; then \ + $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) -schedule-vio2vo $(J) $$VIOFILES; \ + fi +.PHONY: quick2vo + +checkproofs: + $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) \ + -schedule-vio-checking $(J) $(VOFILES:%.vo=%.vio) +.PHONY: checkproofs + +validate: $(VOFILES) + $(TIMER) $(COQCHK) $(COQCHKFLAGS) $(COQLIBS) $^ +.PHONY: validate + +only: $(TGTS) +.PHONY: only + +# Documentation targets ####################################################### + +html: $(GLOBFILES) $(VFILES) + $(SHOW)'COQDOC -d html $(GAL)' + $(HIDE)mkdir -p html + $(HIDE)$(COQDOC) \ + -toc $(COQDOCFLAGS) -html $(GAL) $(COQDOCLIBS) -d html $(VFILES) + +mlihtml: $(MLIFILES:.mli=.cmi) + $(SHOW)'CAMLDOC -d $@' + $(HIDE)mkdir $@ || rm -rf $@/* + $(HIDE)$(CAMLDOC) -html \ + -d $@ -m A $(CAMLDEBUG) $(CAMLDOCFLAGS) $(MLIFILES) + +all-mli.tex: $(MLIFILES:.mli=.cmi) + $(SHOW)'CAMLDOC -latex $@' + $(HIDE)$(CAMLDOC) -latex \ + -o $@ -m A $(CAMLDEBUG) $(CAMLDOCFLAGS) $(MLIFILES) + +all.ps: $(VFILES) + $(SHOW)'COQDOC -ps $(GAL)' + $(HIDE)$(COQDOC) \ + -toc $(COQDOCFLAGS) -ps $(GAL) $(COQDOCLIBS) \ + -o $@ `$(COQDEP) -sort -suffix .v $(VFILES)` + +all.pdf: $(VFILES) + $(SHOW)'COQDOC -pdf $(GAL)' + $(HIDE)$(COQDOC) \ + -toc $(COQDOCFLAGS) -pdf $(GAL) $(COQDOCLIBS) \ + -o $@ `$(COQDEP) -sort -suffix .v $(VFILES)` + +# FIXME: not quite right, since the output name is different +gallinahtml: GAL=-g +gallinahtml: html + +all-gal.ps: GAL=-g +all-gal.ps: all.ps + +all-gal.pdf: GAL=-g +all-gal.pdf: all.pdf + +# ? +beautify: $(BEAUTYFILES) + for file in $^; do mv $${file%.beautified} $${file%beautified}old && mv $${file} $${file%.beautified}; done + @echo 'Do not do "make clean" until you are sure that everything went well!' + @echo 'If there were a problem, execute "for file in $$(find . -name \*.v.old -print); do mv $${file} $${file%.old}; done" in your shell/' +.PHONY: beautify + +# Installation targets ######################################################## +# +# There rules can be extended in Makefile.local +# Extensions can't assume when they run. + +install: + $(HIDE)for f in $(FILESTOINSTALL); do\ + df="`$(COQMKFILE) -destination-of "$$f" $(COQLIBS)`";\ + if [ "$$?" != "0" -o -z "$$df" ]; then\ + echo SKIP "$$f" since it has no logical path;\ + else\ + install -d "$(COQLIBINSTALL)/$$df" &&\ + install -m 0644 "$$f" "$(COQLIBINSTALL)/$$df" &&\ + echo INSTALL "$$f" "$(COQLIBINSTALL)/$$df";\ + fi;\ + done + $(HIDE)$(MAKE) install-extra -f "$(SELF)" +install-extra:: + @# Extension point +.PHONY: install install-extra + +install-byte: + $(HIDE)for f in $(BYTEFILESTOINSTALL); do\ + df="`$(COQMKFILE) -destination-of "$$f" $(COQLIBS)`";\ + if [ "$$?" != "0" -o -z "$$df" ]; then\ + echo SKIP "$$f" since it has no logical path;\ + else\ + install -d "$(COQLIBINSTALL)/$$df" &&\ + install -m 0644 "$$f" "$(COQLIBINSTALL)/$$df" &&\ + echo INSTALL "$$f" "$(COQLIBINSTALL)/$$df";\ + fi;\ + done + +install-doc:: html mlihtml + @# Extension point + $(HIDE)install -d "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/html" + $(HIDE)for i in html/*; do \ + dest="$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/$$i";\ + install -m 0644 "$$i" "$$dest";\ + echo INSTALL "$$i" "$$dest";\ + done + $(HIDE)install -d \ + "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/mlihtml" + $(HIDE)for i in mlihtml/*; do \ + dest="$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/$$i";\ + install -m 0644 "$$i" "$$dest";\ + echo INSTALL "$$i" "$$dest";\ + done +.PHONY: install-doc + +uninstall:: + @# Extension point + $(HIDE)for f in $(FILESTOINSTALL); do \ + df="`$(COQMKFILE) -destination-of "$$f" $(COQLIBS)`" &&\ + instf="$(COQLIBINSTALL)/$$df/`basename $$f`" &&\ + rm -f "$$instf" &&\ + echo RM "$$instf" &&\ + (rmdir "$(call concat_path,,$(COQLIBINSTALL)/$$df/)" 2>/dev/null || true); \ + done +.PHONY: uninstall + +uninstall-doc:: + @# Extension point + $(SHOW)'RM $(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/html' + $(HIDE)rm -rf "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/html" + $(SHOW)'RM $(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/mlihtml' + $(HIDE)rm -rf "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/mlihtml" + $(HIDE) rmdir "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/" || true +.PHONY: uninstall-doc + +# Cleaning #################################################################### +# +# There rules can be extended in Makefile.local +# Extensions can't assume when they run. + +clean:: + @# Extension point + $(SHOW)'CLEAN' + $(HIDE)rm -f $(CMOFILES) + $(HIDE)rm -f $(CMIFILES) + $(HIDE)rm -f $(CMAFILES) + $(HIDE)rm -f $(CMOFILES:.cmo=.cmx) + $(HIDE)rm -f $(CMXAFILES) + $(HIDE)rm -f $(CMXSFILES) + $(HIDE)rm -f $(CMOFILES:.cmo=.o) + $(HIDE)rm -f $(CMXAFILES:.cmxa=.a) + $(HIDE)rm -f $(ALLDFILES) + $(HIDE)rm -f $(NATIVEFILES) + $(HIDE)find . -name .coq-native -type d -empty -delete + $(HIDE)rm -f $(VOFILES) + $(HIDE)rm -f $(VOFILES:.vo=.vio) + $(HIDE)rm -f $(BEAUTYFILES) $(VFILES:=.old) + $(HIDE)rm -f all.ps all-gal.ps all.pdf all-gal.pdf all.glob all-mli.tex + $(HIDE)rm -f $(VFILES:.v=.glob) + $(HIDE)rm -f $(VFILES:.v=.tex) + $(HIDE)rm -f $(VFILES:.v=.g.tex) + $(HIDE)rm -f pretty-timed-success.ok + $(HIDE)rm -rf html mlihtml +.PHONY: clean + +cleanall:: clean + @# Extension point + $(SHOW)'CLEAN *.aux *.timing' + $(HIDE)rm -f $(foreach f,$(VFILES:.v=),$(dir $(f)).$(notdir $(f)).aux) + $(HIDE)rm -f $(TIME_OF_BUILD_FILE) $(TIME_OF_BUILD_BEFORE_FILE) $(TIME_OF_BUILD_AFTER_FILE) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BOTH_BUILD_FILE) + $(HIDE)rm -f $(VOFILES:.vo=.v.timing) + $(HIDE)rm -f $(VOFILES:.vo=.v.before-timing) + $(HIDE)rm -f $(VOFILES:.vo=.v.after-timing) + $(HIDE)rm -f $(VOFILES:.vo=.v.timing.diff) +.PHONY: cleanall + +archclean:: + @# Extension point + $(SHOW)'CLEAN *.cmx *.o' + $(HIDE)rm -f $(NATIVEFILES) + $(HIDE)rm -f $(CMOFILES:%.cmo=%.cmx) +.PHONY: archclean + + +# Compilation rules ########################################################### + +$(MLIFILES:.mli=.cmi): %.cmi: %.mli + $(SHOW)'CAMLC -c $<' + $(HIDE)$(CAMLC) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) $< + +$(ML4FILES:.ml4=.cmo): %.cmo: %.ml4 + $(SHOW)'CAMLC -pp -c $<' + $(HIDE)$(CAMLC) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) $(PP) -impl $< + +$(ML4FILES:.ml4=.cmx): %.cmx: %.ml4 + $(SHOW)'CAMLOPT -pp -c $(FOR_PACK) $<' + $(HIDE)$(CAMLOPTC) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) $(PP) $(FOR_PACK) -impl $< + +$(MLFILES:.ml=.cmo): %.cmo: %.ml + $(SHOW)'CAMLC -c $<' + $(HIDE)$(CAMLC) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) $< + +$(MLFILES:.ml=.cmx): %.cmx: %.ml + $(SHOW)'CAMLOPT -c $(FOR_PACK) $<' + $(HIDE)$(CAMLOPTC) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) $(FOR_PACK) $< + + +$(MLLIBFILES:.mllib=.cmxs): %.cmxs: %.cmxa + $(SHOW)'CAMLOPT -shared -o $@' + $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) \ + -linkall -shared -o $@ $< + +$(MLLIBFILES:.mllib=.cma): %.cma: | %.mllib + $(SHOW)'CAMLC -a -o $@' + $(HIDE)$(CAMLLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) -a -o $@ $^ + +$(MLLIBFILES:.mllib=.cmxa): %.cmxa: | %.mllib + $(SHOW)'CAMLOPT -a -o $@' + $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) -a -o $@ $^ + + +$(MLPACKFILES:.mlpack=.cmxs): %.cmxs: %.cmxa + $(SHOW)'CAMLOPT -shared -o $@' + $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) \ + -shared -linkall -o $@ $< + +$(MLPACKFILES:.mlpack=.cmxa): %.cmxa: %.cmx + $(SHOW)'CAMLOPT -a -o $@' + $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) -a -o $@ $< + +$(MLPACKFILES:.mlpack=.cma): %.cma: %.cmo | %.mlpack + $(SHOW)'CAMLC -a -o $@' + $(HIDE)$(CAMLLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) -a -o $@ $^ + +$(MLPACKFILES:.mlpack=.cmo): %.cmo: | %.mlpack + $(SHOW)'CAMLC -pack -o $@' + $(HIDE)$(CAMLLINK) $(CAMLDEBUG) $(CAMLFLAGS) -pack -o $@ $^ + +$(MLPACKFILES:.mlpack=.cmx): %.cmx: | %.mlpack + $(SHOW)'CAMLOPT -pack -o $@' + $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) -pack -o $@ $^ + +# This rule is for _CoqProject with no .mllib nor .mlpack +$(filter-out $(MLLIBFILES:.mllib=.cmxs) $(MLPACKFILES:.mlpack=.cmxs) $(addsuffix .cmxs,$(PACKEDFILES)) $(addsuffix .cmxs,$(LIBEDFILES)),$(MLFILES:.ml=.cmxs) $(ML4FILES:.ml4=.cmxs)): %.cmxs: %.cmx + $(SHOW)'[deprecated,use-mllib-or-mlpack] CAMLOPT -shared -o $@' + $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) \ + -shared -o $@ $< + +ifneq (,$(TIMING)) +TIMING_EXTRA = > $<.$(TIMING_EXT) +else +TIMING_EXTRA = +endif + +$(VOFILES): %.vo: %.v + $(SHOW)COQC $< + $(HIDE)$(TIMER) $(COQC) $(COQDEBUG) $(TIMING_ARG) $(COQFLAGS) $(COQLIBS) $< $(TIMING_EXTRA) + +# FIXME ?merge with .vo / .vio ? +$(GLOBFILES): %.glob: %.v + $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) $< + +$(VFILES:.v=.vio): %.vio: %.v + $(SHOW)COQC -quick $< + $(HIDE)$(TIMER) $(COQC) -quick $(COQDEBUG) $(COQFLAGS) $(COQLIBS) $< + +$(addsuffix .timing.diff,$(VFILES)): %.timing.diff : %.before-timing %.after-timing + $(SHOW)PYTHON TIMING-DIFF $< + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" print-pretty-single-time-diff BEFORE=$*.before-timing AFTER=$*.after-timing TIME_OF_PRETTY_BUILD_FILE="$@" + +$(BEAUTYFILES): %.v.beautified: %.v + $(SHOW)'BEAUTIFY $<' + $(HIDE)$(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) -beautify $< + +$(TEXFILES): %.tex: %.v + $(SHOW)'COQDOC -latex $<' + $(HIDE)$(COQDOC) $(COQDOCFLAGS) -latex $< -o $@ + +$(GTEXFILES): %.g.tex: %.v + $(SHOW)'COQDOC -latex -g $<' + $(HIDE)$(COQDOC) $(COQDOCFLAGS) -latex -g $< -o $@ + +$(HTMLFILES): %.html: %.v %.glob + $(SHOW)'COQDOC -html $<' + $(HIDE)$(COQDOC) $(COQDOCFLAGS) -html $< -o $@ + +$(GHTMLFILES): %.g.html: %.v %.glob + $(SHOW)'COQDOC -html -g $<' + $(HIDE)$(COQDOC) $(COQDOCFLAGS) -html -g $< -o $@ + +# Dependency files ############################################################ + +ifneq ($(filter-out archclean clean cleanall printenv make-pretty-timed make-pretty-timed-before make-pretty-timed-after print-pretty-timed print-pretty-timed-diff print-pretty-single-time-diff,$(MAKECMDGOALS)),) + -include $(ALLDFILES) +else + ifeq ($(MAKECMDGOALS),) + -include $(ALLDFILES) + endif +endif + +.SECONDARY: $(ALLDFILES) + +redir_if_ok = > "$@" || ( RV=$$?; rm -f "$@"; exit $$RV ) + +$(addsuffix .d,$(MLIFILES)): %.mli.d: %.mli + $(SHOW)'CAMLDEP $<' + $(HIDE)$(CAMLDEP) $(OCAMLLIBS) "$<" $(redir_if_ok) + +$(addsuffix .d,$(ML4FILES)): %.ml4.d: %.ml4 + $(SHOW)'CAMLDEP -pp $<' + $(HIDE)$(CAMLDEP) $(OCAMLLIBS) $(PP) -impl "$<" $(redir_if_ok) + +$(addsuffix .d,$(MLFILES)): %.ml.d: %.ml + $(SHOW)'CAMLDEP $<' + $(HIDE)$(CAMLDEP) $(OCAMLLIBS) "$<" $(redir_if_ok) + +$(addsuffix .d,$(MLLIBFILES)): %.mllib.d: %.mllib + $(SHOW)'COQDEP $<' + $(HIDE)$(COQDEP) $(OCAMLLIBS) -c "$<" $(redir_if_ok) + +$(addsuffix .d,$(MLPACKFILES)): %.mlpack.d: %.mlpack + $(SHOW)'COQDEP $<' + $(HIDE)$(COQDEP) $(OCAMLLIBS) -c "$<" $(redir_if_ok) + +# If this makefile is created using a _CoqProject we have coqdep get +# options from it. This avoids argument length limits for pathological +# projects. Note that extra options might be on the command line. +VDFILE_FLAGS:=$(if _CoqProject,-f _CoqProject,) $(CMDLINE_COQLIBS) $(CMDLINE_VFILES) + +$(VDFILE).d: $(VFILES) + $(SHOW)'COQDEP VFILES' + $(HIDE)$(COQDEP) -dyndep var $(VDFILE_FLAGS) $(redir_if_ok) + +# Misc ######################################################################## + +byte: + $(HIDE)$(MAKE) all "OPT:=-byte" -f "$(SELF)" +.PHONY: byte + +opt: + $(HIDE)$(MAKE) all "OPT:=-opt" -f "$(SELF)" +.PHONY: opt + +# This is deprecated. To extend this makefile use +# extension points and Makefile.local +printenv:: + $(warning printenv is deprecated) + $(warning write extensions in Makefile.local or include Makefile.conf) + @echo 'LOCAL = $(LOCAL)' + @echo 'COQLIB = $(COQLIB)' + @echo 'DOCDIR = $(DOCDIR)' + @echo 'OCAMLFIND = $(OCAMLFIND)' + @echo 'CAMLP5O = $(CAMLP5O)' + @echo 'CAMLP5BIN = $(CAMLP5BIN)' + @echo 'CAMLP5LIB = $(CAMLP5LIB)' + @echo 'CAMLP5OPTIONS = $(CAMLP5OPTIONS)' + @echo 'HASNATDYNLINK = $(HASNATDYNLINK)' + @echo 'SRC_SUBDIRS = $(SRC_SUBDIRS)' + @echo 'COQ_SRC_SUBDIRS = $(COQ_SRC_SUBDIRS)' + @echo 'OCAMLFIND = $(OCAMLFIND)' + @echo 'PP = $(PP)' + @echo 'COQFLAGS = $(COQFLAGS)' + @echo 'COQLIB = $(COQLIBS)' + @echo 'COQLIBINSTALL = $(COQLIBINSTALL)' + @echo 'COQDOCINSTALL = $(COQDOCINSTALL)' +.PHONY: printenv + +# Generate a .merlin file. If you need to append directives to this +# file you can extend the merlin-hook target in Makefile.local +.merlin: + $(SHOW)'FILL .merlin' + $(HIDE)echo 'FLG $(COQMF_CAMLFLAGS)' > .merlin + $(HIDE)echo 'B $(COQLIB)' >> .merlin + $(HIDE)echo 'S $(COQLIB)' >> .merlin + $(HIDE)$(foreach d,$(COQ_SRC_SUBDIRS), \ + echo 'B $(COQLIB)$(d)' >> .merlin;) + $(HIDE)$(foreach d,$(COQ_SRC_SUBDIRS), \ + echo 'S $(COQLIB)$(d)' >> .merlin;) + $(HIDE)$(foreach d,$(SRC_SUBDIRS), echo 'B $(d)' >> .merlin;) + $(HIDE)$(foreach d,$(SRC_SUBDIRS), echo 'S $(d)' >> .merlin;) + $(HIDE)$(MAKE) merlin-hook -f "$(SELF)" +.PHONY: merlin + +merlin-hook:: + @# Extension point +.PHONY: merlin-hook + +# prints all variables +debug: + $(foreach v,\ + $(sort $(filter-out $(INITIAL_VARS) INITIAL_VARS,\ + $(.VARIABLES))),\ + $(info $(v) = $($(v)))) +.PHONY: debug + +.DEFAULT_GOAL := all diff --git a/Makefile.local b/Makefile.local new file mode 100644 index 0000000..33f2bd1 --- /dev/null +++ b/Makefile.local @@ -0,0 +1 @@ +CAMLPKGS+= -package sexplib0 -package parsexp -package sexplib -package ppx_deriving -package coq-serapi -package pyml \ No newline at end of file diff --git a/_CoqProject b/_CoqProject index 339b268..847eaf5 100644 --- a/_CoqProject +++ b/_CoqProject @@ -91,7 +91,7 @@ src/coq/devutils/printing.ml src/coq/decompiler/decompiler.mli src/coq/decompiler/decompiler.ml -src/plibrary.ml4 src/plib.mlpack +src/plibrary.ml4 theories/Plib.v diff --git a/coq-serapi b/coq-serapi new file mode 160000 index 0000000..ce85229 --- /dev/null +++ b/coq-serapi @@ -0,0 +1 @@ +Subproject commit ce852291928008bc0e482b7d1c95ae2e214c74b0 diff --git a/pyml b/pyml new file mode 160000 index 0000000..b6608db --- /dev/null +++ b/pyml @@ -0,0 +1 @@ +Subproject commit b6608db88f0559f7e59b9be859a649f5bb6812b7 diff --git a/src/plib.mlpack b/src/plib.mlpack index 2d376a0..d3cfa95 100644 --- a/src/plib.mlpack +++ b/src/plib.mlpack @@ -43,5 +43,7 @@ Printing Decompiler -Plibrary +Pyml +Serlib +Plibrary \ No newline at end of file diff --git a/src/plibrary.ml4 b/src/plibrary.ml4 index 197773c..7814deb 100644 --- a/src/plibrary.ml4 +++ b/src/plibrary.ml4 @@ -1 +1,54 @@ + DECLARE PLUGIN "plib" + +open Decompiler +open Constr +open Names +open Environ +open Assumptions +open Search +open Evd +open Printing +open Reducers +open Stdarg +open Utilities +open Zooming +open Defutils +open Envutils +open Stateutils +open Inference +open Tactics +open Pp +open Ltac_plugin +open Nameutils + +open Class_tactics +open Stdarg +open Tacarg +open Pyml +open Serlib + +(* --- Commands --- *) + +(* Decompiles a single term into a tactic list printed to console. *) +let decompile_command trm tacs = + let (sigma, env) = Pfedit.get_current_context () in + let sigma, trm = intern env sigma trm in + let trm = unwrap_definition env trm in + let opts = List.map (fun s -> (parse_tac_str s, s)) tacs in + let sigma, script = tac_from_term env sigma (fun _ sigma [] _ -> sigma, opts) trm in + (* let sigma, goal = infer_type env sigma trm in *) + (* Feedback.msg_warning (ppx_conv_sexp env sigma goal) *) + (* Feedback.msg_warning (str "the goal: " ++ Printer.pr_constr_env env sigma goal) *) + (* Feedback.msg_debug (script) *) + Feedback.msg_debug (tac_to_string sigma script) + +(* --- Vernac syntax --- *) + +(* Decompile Command *) +VERNAC COMMAND EXTEND Decompile CLASSIFIED AS SIDEFF +| [ "Decompile" constr(trm) ] -> + [ decompile_command trm [] ] +| [ "Decompile" constr(trm) "with" string_list(l) ] -> + [ decompile_command trm l ] +END \ No newline at end of file diff --git a/theories/Plib.v b/theories/Plib.v index 87e32df..fe50713 100644 --- a/theories/Plib.v +++ b/theories/Plib.v @@ -1 +1,6 @@ Declare ML Module "plib". +(* Add ML Path "/Users/emilyfirst/.opam/4.07.1+flambda/lib/coq-serapi/serlib". *) +(* Add ML Path "/Users/emilyfirst/.opam/4.07.1+flambda/lib/pyml". *) + +(* Declare ML Module "serlib". *) + From 11f8859a08259018c4f529af52127bfd15cb25c4 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 7 Sep 2021 16:06:54 -0500 Subject: [PATCH 08/39] minimize dependencies for pyml --- pyml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyml b/pyml index b6608db..1beb1a5 160000 --- a/pyml +++ b/pyml @@ -1 +1 @@ -Subproject commit b6608db88f0559f7e59b9be859a649f5bb6812b7 +Subproject commit 1beb1a57933684bfe740f8e6dd4d2223aa2fe776 From 0ae0d3bc57558771d816cc20877cda437c0b7e9d Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 7 Sep 2021 16:09:04 -0500 Subject: [PATCH 09/39] minimize dependencies in mli file --- pyml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyml b/pyml index 1beb1a5..1622410 160000 --- a/pyml +++ b/pyml @@ -1 +1 @@ -Subproject commit 1beb1a57933684bfe740f8e6dd4d2223aa2fe776 +Subproject commit 1622410f4c594982f9d5ea421ec0639bc68072dc From b25c926b7409522b51736822a6368b2e61243fbf Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 7 Sep 2021 16:13:07 -0500 Subject: [PATCH 10/39] Try to remove Stdcompat from pyml --- pyml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyml b/pyml index 1622410..a378e36 160000 --- a/pyml +++ b/pyml @@ -1 +1 @@ -Subproject commit 1622410f4c594982f9d5ea421ec0639bc68072dc +Subproject commit a378e36084b3e6ff1d02dbfe4144b5456f41abd9 From de1a080eb2c21a9c07db583efac9e58394b4f77e Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 7 Sep 2021 16:32:39 -0500 Subject: [PATCH 11/39] add rectypes to Makefile --- pyml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyml b/pyml index a378e36..6e7c46f 160000 --- a/pyml +++ b/pyml @@ -1 +1 @@ -Subproject commit a378e36084b3e6ff1d02dbfe4144b5456f41abd9 +Subproject commit 6e7c46fcb09639222ede3db6a4270848c6f8b781 From 3d16d4867472674e2d8e664492589b6a4f68c8f4 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 7 Sep 2021 16:59:25 -0500 Subject: [PATCH 12/39] finish inlining 4.08 OCaml functions.. --- pyml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyml b/pyml index 6e7c46f..f74db58 160000 --- a/pyml +++ b/pyml @@ -1 +1 @@ -Subproject commit 6e7c46fcb09639222ede3db6a4270848c6f8b781 +Subproject commit f74db5886fee3fc7c91902f603c6be92d897e008 From 91f289f3c3845a39d2ee183ff8147363e1973e19 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 7 Sep 2021 17:00:11 -0500 Subject: [PATCH 13/39] Update build to work with pyml --- _CoqProject | 12 ++++++++++++ build.sh | 5 +++++ src/plib.mlpack | 11 ++++++++--- src/plibrary.ml4 | 4 ++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/_CoqProject b/_CoqProject index 847eaf5..5f91666 100644 --- a/_CoqProject +++ b/_CoqProject @@ -10,6 +10,7 @@ -I src/coq/logicutils/transformation -I src/coq/devutils -I src/coq/representationutils +-I pyml -I src/coq/decompiler -I src -R src Plibrary @@ -88,6 +89,17 @@ src/coq/logicutils/transformation/transform.ml src/coq/devutils/printing.mli src/coq/devutils/printing.ml +pyml/pyutils.mli +pyml/pyutils.ml +pyml/pytypes.mli +pyml/pytypes.ml +pyml/pyml_arch.mli +pyml/pyml_arch.ml +pyml/pywrappers.mli +pyml/pywrappers.ml +pyml/py.mli +pyml/py.ml + src/coq/decompiler/decompiler.mli src/coq/decompiler/decompiler.ml diff --git a/build.sh b/build.sh index 99853cb..554a092 100755 --- a/build.sh +++ b/build.sh @@ -1,2 +1,7 @@ +git submodule init +git submodule update +cd pyml +make +cd .. coq_makefile -f _CoqProject -o Makefile make clean && make && make install diff --git a/src/plib.mlpack b/src/plib.mlpack index d3cfa95..afae5f2 100644 --- a/src/plib.mlpack +++ b/src/plib.mlpack @@ -41,9 +41,14 @@ Transform Printing -Decompiler +Pyutils +Pytypes +Pyml_arch +Pywrappers +Py -Pyml Serlib -Plibrary \ No newline at end of file +Decompiler + +Plibrary diff --git a/src/plibrary.ml4 b/src/plibrary.ml4 index 7814deb..b761457 100644 --- a/src/plibrary.ml4 +++ b/src/plibrary.ml4 @@ -25,7 +25,7 @@ open Nameutils open Class_tactics open Stdarg open Tacarg -open Pyml +open Py open Serlib (* --- Commands --- *) @@ -51,4 +51,4 @@ VERNAC COMMAND EXTEND Decompile CLASSIFIED AS SIDEFF [ decompile_command trm [] ] | [ "Decompile" constr(trm) "with" string_list(l) ] -> [ decompile_command trm l ] -END \ No newline at end of file +END From 32206d1d64891a0014c74e4bb71e5d10a1ff3ad7 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 7 Sep 2021 17:22:40 -0500 Subject: [PATCH 14/39] Move SerAPI to 8.9 branch --- coq-serapi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coq-serapi b/coq-serapi index ce85229..58ff162 160000 --- a/coq-serapi +++ b/coq-serapi @@ -1 +1 @@ -Subproject commit ce852291928008bc0e482b7d1c95ae2e214c74b0 +Subproject commit 58ff1622c1472b828eaa22b1d477cb67d4ae6b05 From a144721b21fcf156ca1d390210ace4459c914373 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 7 Sep 2021 17:25:05 -0500 Subject: [PATCH 15/39] get most of SerAPI working, but need Sexplib --- _CoqProject | 13 +++++++++++++ src/plib.mlpack | 2 +- src/plibrary.ml4 | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/_CoqProject b/_CoqProject index 5f91666..d23b5c8 100644 --- a/_CoqProject +++ b/_CoqProject @@ -11,6 +11,8 @@ -I src/coq/devutils -I src/coq/representationutils -I pyml +-I coq-serapi/serapi +-I coq-serapi -I src/coq/decompiler -I src -R src Plibrary @@ -100,6 +102,17 @@ pyml/pywrappers.ml pyml/py.mli pyml/py.ml +coq-serapi/serapi/serapi_assumptions.mli +coq-serapi/serapi/serapi_assumptions.ml +coq-serapi/serapi/serapi_goals.mli +coq-serapi/serapi/serapi_goals.ml +coq-serapi/serapi/serapi_paths.mli +coq-serapi/serapi/serapi_paths.ml +coq-serapi/serapi/serapi_pp.mli +coq-serapi/serapi/serapi_pp.ml +coq-serapi/serapi/serapi_protocol.mli +coq-serapi/serapi/serapi_protocol.ml + src/coq/decompiler/decompiler.mli src/coq/decompiler/decompiler.ml diff --git a/src/plib.mlpack b/src/plib.mlpack index afae5f2..3332de5 100644 --- a/src/plib.mlpack +++ b/src/plib.mlpack @@ -47,7 +47,7 @@ Pyml_arch Pywrappers Py -Serlib +Serapi_protocol Decompiler diff --git a/src/plibrary.ml4 b/src/plibrary.ml4 index b761457..4ee143c 100644 --- a/src/plibrary.ml4 +++ b/src/plibrary.ml4 @@ -26,7 +26,7 @@ open Class_tactics open Stdarg open Tacarg open Py -open Serlib +open Serapi_protocol (* --- Commands --- *) From fbd5c878451240c8ba382d702c1ebd3df0e2e441 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 7 Sep 2021 17:53:59 -0500 Subject: [PATCH 16/39] get sexplib working; opening theory throws error --- _CoqProject | 2 ++ build.sh | 1 + src/plibrary.ml4 | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/_CoqProject b/_CoqProject index d23b5c8..e6aa0c7 100644 --- a/_CoqProject +++ b/_CoqProject @@ -1,3 +1,5 @@ +CAMLPKGS = "-package sexplib" + -I src/utilities -I src/coq -I src/coq/termutils diff --git a/build.sh b/build.sh index 554a092..e6bdc8c 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,4 @@ +opam install sexplib git submodule init git submodule update cd pyml diff --git a/src/plibrary.ml4 b/src/plibrary.ml4 index 4ee143c..445a1db 100644 --- a/src/plibrary.ml4 +++ b/src/plibrary.ml4 @@ -25,6 +25,8 @@ open Nameutils open Class_tactics open Stdarg open Tacarg + +open List open Py open Serapi_protocol @@ -35,7 +37,7 @@ let decompile_command trm tacs = let (sigma, env) = Pfedit.get_current_context () in let sigma, trm = intern env sigma trm in let trm = unwrap_definition env trm in - let opts = List.map (fun s -> (parse_tac_str s, s)) tacs in + let opts = map (fun s -> (parse_tac_str s, s)) tacs in let sigma, script = tac_from_term env sigma (fun _ sigma [] _ -> sigma, opts) trm in (* let sigma, goal = infer_type env sigma trm in *) (* Feedback.msg_warning (ppx_conv_sexp env sigma goal) *) From c9bb6e2894995d6f1ce91d291e708e38878683bf Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 7 Sep 2021 19:05:10 -0500 Subject: [PATCH 17/39] try to port to dune --- .gitmodules | 6 -- Makefile.local | 1 - _CoqProject | 124 ------------------------------- build.sh | 3 +- coq-plugin-lib.opam | 19 +++++ coq-serapi | 1 - dune | 3 + dune-project | 3 + pyml | 1 - src/coq/constants/dune | 3 + src/coq/decompiler/dune | 3 + src/coq/devutils/dune | 3 + src/coq/logicutils/dune | 3 + src/coq/representationutils/dune | 3 + src/coq/termutils/dune | 3 + src/dune | 22 ++++++ src/plib.mlpack | 54 -------------- src/utilities/dune | 3 + 18 files changed, 69 insertions(+), 189 deletions(-) delete mode 100644 Makefile.local delete mode 100644 _CoqProject create mode 100644 coq-plugin-lib.opam delete mode 160000 coq-serapi create mode 100644 dune create mode 100644 dune-project delete mode 160000 pyml create mode 100644 src/coq/constants/dune create mode 100644 src/coq/decompiler/dune create mode 100644 src/coq/devutils/dune create mode 100644 src/coq/logicutils/dune create mode 100644 src/coq/representationutils/dune create mode 100644 src/coq/termutils/dune create mode 100644 src/dune create mode 100644 src/utilities/dune diff --git a/.gitmodules b/.gitmodules index 57f1151..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +0,0 @@ -[submodule "pyml"] - path = pyml - url = https://github.com/thierry-martinez/pyml -[submodule "coq-serapi"] - path = coq-serapi - url = https://github.com/ejgallego/coq-serapi diff --git a/Makefile.local b/Makefile.local deleted file mode 100644 index 33f2bd1..0000000 --- a/Makefile.local +++ /dev/null @@ -1 +0,0 @@ -CAMLPKGS+= -package sexplib0 -package parsexp -package sexplib -package ppx_deriving -package coq-serapi -package pyml \ No newline at end of file diff --git a/_CoqProject b/_CoqProject deleted file mode 100644 index e6aa0c7..0000000 --- a/_CoqProject +++ /dev/null @@ -1,124 +0,0 @@ -CAMLPKGS = "-package sexplib" - --I src/utilities --I src/coq --I src/coq/termutils --I src/coq/constants --I src/coq/logicutils --I src/coq/logicutils/contexts --I src/coq/logicutils/typesandequality --I src/coq/logicutils/hofs --I src/coq/logicutils/inductive --I src/coq/logicutils/transformation --I src/coq/devutils --I src/coq/representationutils --I pyml --I coq-serapi/serapi --I coq-serapi --I src/coq/decompiler --I src --R src Plibrary --Q theories Plibrary - -src/utilities/utilities.mli -src/utilities/utilities.ml - -src/coq/termutils/apputils.mli -src/coq/termutils/apputils.ml -src/coq/termutils/constutils.mli -src/coq/termutils/constutils.ml -src/coq/termutils/funutils.mli -src/coq/termutils/funutils.ml - -src/coq/representationutils/defutils.mli -src/coq/representationutils/defutils.ml -src/coq/representationutils/nameutils.mli -src/coq/representationutils/nameutils.ml - -src/coq/logicutils/typesandequality/inference.mli -src/coq/logicutils/typesandequality/inference.ml -src/coq/logicutils/typesandequality/convertibility.mli -src/coq/logicutils/typesandequality/convertibility.ml -src/coq/logicutils/typesandequality/checking.mli -src/coq/logicutils/typesandequality/checking.ml - -src/coq/constants/equtils.mli -src/coq/constants/equtils.ml -src/coq/constants/sigmautils.mli -src/coq/constants/sigmautils.ml -src/coq/constants/produtils.mli -src/coq/constants/produtils.ml -src/coq/constants/idutils.mli -src/coq/constants/idutils.ml -src/coq/constants/proputils.ml -src/coq/constants/proputils.mli - -src/coq/logicutils/contexts/stateutils.mli -src/coq/logicutils/contexts/stateutils.ml -src/coq/logicutils/contexts/envutils.mli -src/coq/logicutils/contexts/envutils.ml -src/coq/logicutils/contexts/contextutils.mli -src/coq/logicutils/contexts/contextutils.ml - -src/coq/logicutils/hofs/hofs.mli -src/coq/logicutils/hofs/hofs.ml -src/coq/logicutils/hofs/hofimpls.mli -src/coq/logicutils/hofs/hofimpls.ml -src/coq/logicutils/hofs/debruijn.mli -src/coq/logicutils/hofs/debruijn.ml -src/coq/logicutils/hofs/substitution.mli -src/coq/logicutils/hofs/substitution.ml -src/coq/logicutils/hofs/reducers.mli -src/coq/logicutils/hofs/reducers.ml -src/coq/logicutils/hofs/typehofs.mli -src/coq/logicutils/hofs/typehofs.ml -src/coq/logicutils/hofs/zooming.mli -src/coq/logicutils/hofs/zooming.ml -src/coq/logicutils/hofs/hypotheses.mli -src/coq/logicutils/hofs/hypotheses.ml -src/coq/logicutils/hofs/filters.mli -src/coq/logicutils/hofs/filters.ml - -src/coq/logicutils/inductive/indexing.mli -src/coq/logicutils/inductive/indexing.ml -src/coq/logicutils/inductive/indutils.mli -src/coq/logicutils/inductive/indutils.ml - -src/coq/logicutils/contexts/modutils.mli -src/coq/logicutils/contexts/modutils.ml - -src/coq/logicutils/transformation/transform.mli -src/coq/logicutils/transformation/transform.ml - -src/coq/devutils/printing.mli -src/coq/devutils/printing.ml - -pyml/pyutils.mli -pyml/pyutils.ml -pyml/pytypes.mli -pyml/pytypes.ml -pyml/pyml_arch.mli -pyml/pyml_arch.ml -pyml/pywrappers.mli -pyml/pywrappers.ml -pyml/py.mli -pyml/py.ml - -coq-serapi/serapi/serapi_assumptions.mli -coq-serapi/serapi/serapi_assumptions.ml -coq-serapi/serapi/serapi_goals.mli -coq-serapi/serapi/serapi_goals.ml -coq-serapi/serapi/serapi_paths.mli -coq-serapi/serapi/serapi_paths.ml -coq-serapi/serapi/serapi_pp.mli -coq-serapi/serapi/serapi_pp.ml -coq-serapi/serapi/serapi_protocol.mli -coq-serapi/serapi/serapi_protocol.ml - -src/coq/decompiler/decompiler.mli -src/coq/decompiler/decompiler.ml - -src/plib.mlpack -src/plibrary.ml4 - -theories/Plib.v diff --git a/build.sh b/build.sh index e6bdc8c..9eaa509 100755 --- a/build.sh +++ b/build.sh @@ -4,5 +4,4 @@ git submodule update cd pyml make cd .. -coq_makefile -f _CoqProject -o Makefile -make clean && make && make install +dune build diff --git a/coq-plugin-lib.opam b/coq-plugin-lib.opam new file mode 100644 index 0000000..45fe339 --- /dev/null +++ b/coq-plugin-lib.opam @@ -0,0 +1,19 @@ +synopsis: "Coq Plugin Library" +description: "Coq Plugin Library" +name: "coq-plugin-lib" +opam-version: "2.0" +maintainer: "talia@dependenttyp.es" +authors: "Talia Ringer" +homepage: "https://github.com/uwplse/coq-plugin-lib" +bug-reports: "https://github.com/uwplse/coq-plugin-lib" +dev-repo: "git+https://github.com/uwplse/coq-plugin-lib" +license: "MIT" +doc: "https://github.com/uwplse/coq-plugin-lib" + +depends: [ + "ocaml" { = "4.07.1+flambda" } + "coq" { = "8.9.1" } + "dune" { build & >= "1.9.0" } +] + +build: [ "dune" "build" "-p" name "-j" jobs ] diff --git a/coq-serapi b/coq-serapi deleted file mode 160000 index 58ff162..0000000 --- a/coq-serapi +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 58ff1622c1472b828eaa22b1d477cb67d4ae6b05 diff --git a/dune b/dune new file mode 100644 index 0000000..5dbc4db --- /dev/null +++ b/dune @@ -0,0 +1,3 @@ +(env + (dev (flags :standard -rectypes)) + (release (flags :standard -rectypes))) diff --git a/dune-project b/dune-project new file mode 100644 index 0000000..777fbba --- /dev/null +++ b/dune-project @@ -0,0 +1,3 @@ +(lang dune 1.10) +(using coq 0.1) +(name coq-plugin-lib) diff --git a/pyml b/pyml deleted file mode 160000 index f74db58..0000000 --- a/pyml +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f74db5886fee3fc7c91902f603c6be92d897e008 diff --git a/src/coq/constants/dune b/src/coq/constants/dune new file mode 100644 index 0000000..7446bf6 --- /dev/null +++ b/src/coq/constants/dune @@ -0,0 +1,3 @@ +(library + (name constants) + (public_name coq-plugin-lib.constants)) diff --git a/src/coq/decompiler/dune b/src/coq/decompiler/dune new file mode 100644 index 0000000..570f71b --- /dev/null +++ b/src/coq/decompiler/dune @@ -0,0 +1,3 @@ +(library + (name decompiler) + (public_name coq-plugin-lib.decompiler)) diff --git a/src/coq/devutils/dune b/src/coq/devutils/dune new file mode 100644 index 0000000..9a264df --- /dev/null +++ b/src/coq/devutils/dune @@ -0,0 +1,3 @@ +(library + (name devutils) + (public_name coq-plugin-lib.devutils)) diff --git a/src/coq/logicutils/dune b/src/coq/logicutils/dune new file mode 100644 index 0000000..e95a447 --- /dev/null +++ b/src/coq/logicutils/dune @@ -0,0 +1,3 @@ +(library + (name logicutils) + (public_name coq-plugin-lib.logicutils)) diff --git a/src/coq/representationutils/dune b/src/coq/representationutils/dune new file mode 100644 index 0000000..8bc4629 --- /dev/null +++ b/src/coq/representationutils/dune @@ -0,0 +1,3 @@ +(library + (name representationutils) + (public_name coq-plugin-lib.representationutils)) diff --git a/src/coq/termutils/dune b/src/coq/termutils/dune new file mode 100644 index 0000000..c9651db --- /dev/null +++ b/src/coq/termutils/dune @@ -0,0 +1,3 @@ +(library + (name termutils) + (public_name coq-plugin-lib.termutils)) diff --git a/src/dune b/src/dune new file mode 100644 index 0000000..a20259b --- /dev/null +++ b/src/dune @@ -0,0 +1,22 @@ +(library + (name coq_plugin_lib) + (public_name coq-plugin-lib.plugin) + (synopsis "Coq Plugin Lib") + (flags :standard -w -27) ; CoqPP codes requires this + (libraries + coq.vernac ; needed for vernac extend + coq-plugin-lib.utilities + coq-plugin-lib.constants + coq-plugin-lib.decompiler + coq-plugin-lib.devutils + coq-plugin-lib.logicutils + coq-plugin-lib.representationutils + coq-plugin-lib.termutils +)) + +(rule + (targets plibrary.ml) + (deps (:pp-file plibrary.ml4) ) + (action (bash "camlp5 pa_o.cmo pr_o.cmo %{lib:coq.grammar:grammar.cma} -loc loc -impl %{pp-file} -o %{targets}"))) +; camlp5 may need the following additional libs, YMMV +; pa_op.cmo pr_dump.cmo pa_extend.cmo q_MLast.cmo pa_macro.cmo diff --git a/src/plib.mlpack b/src/plib.mlpack index 3332de5..e69de29 100644 --- a/src/plib.mlpack +++ b/src/plib.mlpack @@ -1,54 +0,0 @@ -Utilities - -Apputils -Constutils -Funutils - -Defutils -Nameutils - -Inference -Convertibility -Checking - -Equtils -Sigmautils -Produtils -Idutils -Proputils - -Stateutils -Envutils -Contextutils - -Hofs -Debruijn -Hofimpls -Substitution -Reducers -Typehofs -Filters -Zooming -Hypotheses -Filters - -Indexing -Indutils - -Modutils - -Transform - -Printing - -Pyutils -Pytypes -Pyml_arch -Pywrappers -Py - -Serapi_protocol - -Decompiler - -Plibrary diff --git a/src/utilities/dune b/src/utilities/dune new file mode 100644 index 0000000..84f1ef8 --- /dev/null +++ b/src/utilities/dune @@ -0,0 +1,3 @@ +(library + (name utilities) + (public_name coq-plugin-lib.utilities)) From 0ef071a8e8beb6c40372e827a258c407f30a579d Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Wed, 8 Sep 2021 12:52:17 -0500 Subject: [PATCH 18/39] Get basic build working with dune --- build.sh | 6 ------ dune | 4 ++-- src/coq/constants/dune | 7 ++++++- src/coq/decompiler/dune | 12 +++++++++++- src/coq/devutils/dune | 9 ++++++++- src/coq/devutils/printing.mli | 2 +- src/coq/logicutils/contexts/dune | 14 ++++++++++++++ .../logicutils/contexts/{ => envs}/contextutils.ml | 0 .../contexts/{ => envs}/contextutils.mli | 2 +- src/coq/logicutils/contexts/envs/dune | 13 +++++++++++++ src/coq/logicutils/contexts/{ => envs}/envutils.ml | 0 .../logicutils/contexts/{ => envs}/envutils.mli | 4 ++-- src/coq/logicutils/contexts/state/dune | 9 +++++++++ .../logicutils/contexts/{ => state}/stateutils.ml | 0 .../logicutils/contexts/{ => state}/stateutils.mli | 0 src/coq/logicutils/{hofs => debruijn}/debruijn.ml | 0 src/coq/logicutils/{hofs => debruijn}/debruijn.mli | 0 src/coq/logicutils/debruijn/dune | 11 +++++++++++ src/coq/logicutils/dune | 3 --- src/coq/logicutils/hofs/dune | 11 +++++++++++ src/coq/logicutils/hofs/impls/dune | 13 +++++++++++++ src/coq/logicutils/hofs/{ => impls}/filters.ml | 0 src/coq/logicutils/hofs/{ => impls}/filters.mli | 0 src/coq/logicutils/hofs/{ => impls}/hofimpls.ml | 0 src/coq/logicutils/hofs/{ => impls}/hofimpls.mli | 0 src/coq/logicutils/hofs/{ => impls}/hypotheses.ml | 0 src/coq/logicutils/hofs/{ => impls}/hypotheses.mli | 0 src/coq/logicutils/hofs/{ => impls}/reducers.ml | 0 src/coq/logicutils/hofs/{ => impls}/reducers.mli | 0 .../logicutils/hofs/{ => impls}/substitution.ml | 0 .../logicutils/hofs/{ => impls}/substitution.mli | 0 src/coq/logicutils/hofs/{ => impls}/typehofs.ml | 0 src/coq/logicutils/hofs/{ => impls}/typehofs.mli | 0 src/coq/logicutils/hofs/{ => impls}/zooming.ml | 0 src/coq/logicutils/hofs/{ => impls}/zooming.mli | 0 src/coq/logicutils/inductive/dune | 10 ++++++++++ src/coq/logicutils/inference/dune | 8 ++++++++ .../{typesandequality => inference}/inference.ml | 0 .../{typesandequality => inference}/inference.mli | 0 src/coq/logicutils/transformation/dune | 10 ++++++++++ src/coq/logicutils/typesandequality/dune | 9 +++++++++ src/coq/representationutils/dune | 8 +++++++- src/coq/termutils/dune | 7 ++++++- src/dune | 10 +++++++++- src/plibrary.ml4 | 2 -- src/utilities/dune | 5 ++++- 46 files changed, 165 insertions(+), 24 deletions(-) create mode 100644 src/coq/logicutils/contexts/dune rename src/coq/logicutils/contexts/{ => envs}/contextutils.ml (100%) rename src/coq/logicutils/contexts/{ => envs}/contextutils.mli (98%) create mode 100644 src/coq/logicutils/contexts/envs/dune rename src/coq/logicutils/contexts/{ => envs}/envutils.ml (100%) rename src/coq/logicutils/contexts/{ => envs}/envutils.mli (94%) create mode 100644 src/coq/logicutils/contexts/state/dune rename src/coq/logicutils/contexts/{ => state}/stateutils.ml (100%) rename src/coq/logicutils/contexts/{ => state}/stateutils.mli (100%) rename src/coq/logicutils/{hofs => debruijn}/debruijn.ml (100%) rename src/coq/logicutils/{hofs => debruijn}/debruijn.mli (100%) create mode 100644 src/coq/logicutils/debruijn/dune delete mode 100644 src/coq/logicutils/dune create mode 100644 src/coq/logicutils/hofs/dune create mode 100644 src/coq/logicutils/hofs/impls/dune rename src/coq/logicutils/hofs/{ => impls}/filters.ml (100%) rename src/coq/logicutils/hofs/{ => impls}/filters.mli (100%) rename src/coq/logicutils/hofs/{ => impls}/hofimpls.ml (100%) rename src/coq/logicutils/hofs/{ => impls}/hofimpls.mli (100%) rename src/coq/logicutils/hofs/{ => impls}/hypotheses.ml (100%) rename src/coq/logicutils/hofs/{ => impls}/hypotheses.mli (100%) rename src/coq/logicutils/hofs/{ => impls}/reducers.ml (100%) rename src/coq/logicutils/hofs/{ => impls}/reducers.mli (100%) rename src/coq/logicutils/hofs/{ => impls}/substitution.ml (100%) rename src/coq/logicutils/hofs/{ => impls}/substitution.mli (100%) rename src/coq/logicutils/hofs/{ => impls}/typehofs.ml (100%) rename src/coq/logicutils/hofs/{ => impls}/typehofs.mli (100%) rename src/coq/logicutils/hofs/{ => impls}/zooming.ml (100%) rename src/coq/logicutils/hofs/{ => impls}/zooming.mli (100%) create mode 100644 src/coq/logicutils/inductive/dune create mode 100644 src/coq/logicutils/inference/dune rename src/coq/logicutils/{typesandequality => inference}/inference.ml (100%) rename src/coq/logicutils/{typesandequality => inference}/inference.mli (100%) create mode 100644 src/coq/logicutils/transformation/dune create mode 100644 src/coq/logicutils/typesandequality/dune diff --git a/build.sh b/build.sh index 9eaa509..7afe3ec 100755 --- a/build.sh +++ b/build.sh @@ -1,7 +1 @@ -opam install sexplib -git submodule init -git submodule update -cd pyml -make -cd .. dune build diff --git a/dune b/dune index 5dbc4db..d8d3aa2 100644 --- a/dune +++ b/dune @@ -1,3 +1,3 @@ (env - (dev (flags :standard -rectypes)) - (release (flags :standard -rectypes))) + (dev (flags (:standard -rectypes -w -8-33-3-27-28-32))) + (release (flags (:standard -rectypes -w -8-33-3-27-28-32)))) diff --git a/src/coq/constants/dune b/src/coq/constants/dune index 7446bf6..6d2f28a 100644 --- a/src/coq/constants/dune +++ b/src/coq/constants/dune @@ -1,3 +1,8 @@ (library (name constants) - (public_name coq-plugin-lib.constants)) + (public_name coq-plugin-lib.constants) + (libraries + coq-plugin-lib.inference + coq-plugin-lib.termutils + coq.kernel) + (wrapped false)) diff --git a/src/coq/decompiler/dune b/src/coq/decompiler/dune index 570f71b..5ca0924 100644 --- a/src/coq/decompiler/dune +++ b/src/coq/decompiler/dune @@ -1,3 +1,13 @@ (library (name decompiler) - (public_name coq-plugin-lib.decompiler)) + (public_name coq-plugin-lib.decompiler) + (libraries + coq-plugin-lib.hofimpls + coq-plugin-lib.devutils + coq-plugin-lib.constants + coq-plugin-lib.inductive + coq-plugin-lib.contexts + coq.engine + coq.kernel + coq.plugins.ltac) + (wrapped false)) diff --git a/src/coq/devutils/dune b/src/coq/devutils/dune index 9a264df..173564a 100644 --- a/src/coq/devutils/dune +++ b/src/coq/devutils/dune @@ -1,3 +1,10 @@ (library (name devutils) - (public_name coq-plugin-lib.devutils)) + (public_name coq-plugin-lib.devutils) + (libraries + coq-plugin-lib.contexts + coq-plugin-lib.utilities + coq.printing + coq.engine + coq.kernel) + (wrapped false)) diff --git a/src/coq/devutils/printing.mli b/src/coq/devutils/printing.mli index d4dc67d..fa62803 100644 --- a/src/coq/devutils/printing.mli +++ b/src/coq/devutils/printing.mli @@ -8,7 +8,7 @@ open Evd (* --- Coq terms --- *) (* Pretty-print a `global_reference` with fancy `constr` coloring. *) -val pr_global_as_constr : global_reference -> Pp.t +val pr_global_as_constr : GlobRef.t -> Pp.t (* Gets a name as a string *) val name_as_string : Name.t -> string diff --git a/src/coq/logicutils/contexts/dune b/src/coq/logicutils/contexts/dune new file mode 100644 index 0000000..a6153d4 --- /dev/null +++ b/src/coq/logicutils/contexts/dune @@ -0,0 +1,14 @@ +(library + (name contexts) + (public_name coq-plugin-lib.contexts) + (libraries + coq-plugin-lib.inductive + coq-plugin-lib.state + coq-plugin-lib.inference + coq-plugin-lib.representationutils + coq-plugin-lib.utilities + coq.kernel + coq.engine + coq.interp + coq.plugins.ltac) + (wrapped false)) diff --git a/src/coq/logicutils/contexts/contextutils.ml b/src/coq/logicutils/contexts/envs/contextutils.ml similarity index 100% rename from src/coq/logicutils/contexts/contextutils.ml rename to src/coq/logicutils/contexts/envs/contextutils.ml diff --git a/src/coq/logicutils/contexts/contextutils.mli b/src/coq/logicutils/contexts/envs/contextutils.mli similarity index 98% rename from src/coq/logicutils/contexts/contextutils.mli rename to src/coq/logicutils/contexts/envs/contextutils.mli index f227051..8e6b292 100644 --- a/src/coq/logicutils/contexts/contextutils.mli +++ b/src/coq/logicutils/contexts/envs/contextutils.mli @@ -133,7 +133,7 @@ val bindings_for_inductive : env -> mutual_inductive_body -> one_inductive_body array -> rel_declaration list val bindings_for_fix : - name array -> types array -> rel_declaration list + Name.t array -> types array -> rel_declaration list (* --- Combining contexts --- *) diff --git a/src/coq/logicutils/contexts/envs/dune b/src/coq/logicutils/contexts/envs/dune new file mode 100644 index 0000000..9ccce56 --- /dev/null +++ b/src/coq/logicutils/contexts/envs/dune @@ -0,0 +1,13 @@ +(library + (name envs) + (public_name coq-plugin-lib.envs) + (libraries + coq-plugin-lib.state + coq-plugin-lib.inference + coq-plugin-lib.representationutils + coq-plugin-lib.utilities + coq.kernel + coq.engine + coq.interp + coq.plugins.ltac) + (wrapped false)) diff --git a/src/coq/logicutils/contexts/envutils.ml b/src/coq/logicutils/contexts/envs/envutils.ml similarity index 100% rename from src/coq/logicutils/contexts/envutils.ml rename to src/coq/logicutils/contexts/envs/envutils.ml diff --git a/src/coq/logicutils/contexts/envutils.mli b/src/coq/logicutils/contexts/envs/envutils.mli similarity index 94% rename from src/coq/logicutils/contexts/envutils.mli rename to src/coq/logicutils/contexts/envs/envutils.mli index 62cc865..f9817b2 100644 --- a/src/coq/logicutils/contexts/envutils.mli +++ b/src/coq/logicutils/contexts/envs/envutils.mli @@ -27,8 +27,8 @@ val rel_name_type : rel_declaration -> Name.t * types (* * Push to an environment *) -val push_local : (name * types) -> env -> env -val push_let_in : (name * types * types) -> env -> env +val push_local : (Name.t * types) -> env -> env +val push_let_in : (Name.t * types * types) -> env -> env (* * Lookup from an environment diff --git a/src/coq/logicutils/contexts/state/dune b/src/coq/logicutils/contexts/state/dune new file mode 100644 index 0000000..7740d54 --- /dev/null +++ b/src/coq/logicutils/contexts/state/dune @@ -0,0 +1,9 @@ +(library + (name state) + (public_name coq-plugin-lib.state) + (libraries + coq-plugin-lib.utilities + coq.kernel + coq.engine + coq.interp) + (wrapped false)) diff --git a/src/coq/logicutils/contexts/stateutils.ml b/src/coq/logicutils/contexts/state/stateutils.ml similarity index 100% rename from src/coq/logicutils/contexts/stateutils.ml rename to src/coq/logicutils/contexts/state/stateutils.ml diff --git a/src/coq/logicutils/contexts/stateutils.mli b/src/coq/logicutils/contexts/state/stateutils.mli similarity index 100% rename from src/coq/logicutils/contexts/stateutils.mli rename to src/coq/logicutils/contexts/state/stateutils.mli diff --git a/src/coq/logicutils/hofs/debruijn.ml b/src/coq/logicutils/debruijn/debruijn.ml similarity index 100% rename from src/coq/logicutils/hofs/debruijn.ml rename to src/coq/logicutils/debruijn/debruijn.ml diff --git a/src/coq/logicutils/hofs/debruijn.mli b/src/coq/logicutils/debruijn/debruijn.mli similarity index 100% rename from src/coq/logicutils/hofs/debruijn.mli rename to src/coq/logicutils/debruijn/debruijn.mli diff --git a/src/coq/logicutils/debruijn/dune b/src/coq/logicutils/debruijn/dune new file mode 100644 index 0000000..3e65d0d --- /dev/null +++ b/src/coq/logicutils/debruijn/dune @@ -0,0 +1,11 @@ +(library + (name debruijn) + (public_name coq-plugin-lib.debruijn) + (libraries + coq-plugin-lib.envs + coq-plugin-lib.hofs + coq-plugin-lib.typesandequality + coq-plugin-lib.utilities + coq.kernel + coq.engine) + (wrapped false)) diff --git a/src/coq/logicutils/dune b/src/coq/logicutils/dune deleted file mode 100644 index e95a447..0000000 --- a/src/coq/logicutils/dune +++ /dev/null @@ -1,3 +0,0 @@ -(library - (name logicutils) - (public_name coq-plugin-lib.logicutils)) diff --git a/src/coq/logicutils/hofs/dune b/src/coq/logicutils/hofs/dune new file mode 100644 index 0000000..3b4141b --- /dev/null +++ b/src/coq/logicutils/hofs/dune @@ -0,0 +1,11 @@ +(library + (name hofs) + (public_name coq-plugin-lib.hofs) + (libraries + coq-plugin-lib.state + coq-plugin-lib.envs + coq-plugin-lib.typesandequality + coq-plugin-lib.utilities + coq.kernel + coq.engine) + (wrapped false)) diff --git a/src/coq/logicutils/hofs/impls/dune b/src/coq/logicutils/hofs/impls/dune new file mode 100644 index 0000000..d762669 --- /dev/null +++ b/src/coq/logicutils/hofs/impls/dune @@ -0,0 +1,13 @@ +(library + (name hofimpls) + (public_name coq-plugin-lib.hofimpls) + (libraries + coq-plugin-lib.termutils + coq-plugin-lib.constants + coq-plugin-lib.debruijn + coq-plugin-lib.hofs + coq-plugin-lib.typesandequality + coq-plugin-lib.utilities + coq.kernel + coq.engine) + (wrapped false)) diff --git a/src/coq/logicutils/hofs/filters.ml b/src/coq/logicutils/hofs/impls/filters.ml similarity index 100% rename from src/coq/logicutils/hofs/filters.ml rename to src/coq/logicutils/hofs/impls/filters.ml diff --git a/src/coq/logicutils/hofs/filters.mli b/src/coq/logicutils/hofs/impls/filters.mli similarity index 100% rename from src/coq/logicutils/hofs/filters.mli rename to src/coq/logicutils/hofs/impls/filters.mli diff --git a/src/coq/logicutils/hofs/hofimpls.ml b/src/coq/logicutils/hofs/impls/hofimpls.ml similarity index 100% rename from src/coq/logicutils/hofs/hofimpls.ml rename to src/coq/logicutils/hofs/impls/hofimpls.ml diff --git a/src/coq/logicutils/hofs/hofimpls.mli b/src/coq/logicutils/hofs/impls/hofimpls.mli similarity index 100% rename from src/coq/logicutils/hofs/hofimpls.mli rename to src/coq/logicutils/hofs/impls/hofimpls.mli diff --git a/src/coq/logicutils/hofs/hypotheses.ml b/src/coq/logicutils/hofs/impls/hypotheses.ml similarity index 100% rename from src/coq/logicutils/hofs/hypotheses.ml rename to src/coq/logicutils/hofs/impls/hypotheses.ml diff --git a/src/coq/logicutils/hofs/hypotheses.mli b/src/coq/logicutils/hofs/impls/hypotheses.mli similarity index 100% rename from src/coq/logicutils/hofs/hypotheses.mli rename to src/coq/logicutils/hofs/impls/hypotheses.mli diff --git a/src/coq/logicutils/hofs/reducers.ml b/src/coq/logicutils/hofs/impls/reducers.ml similarity index 100% rename from src/coq/logicutils/hofs/reducers.ml rename to src/coq/logicutils/hofs/impls/reducers.ml diff --git a/src/coq/logicutils/hofs/reducers.mli b/src/coq/logicutils/hofs/impls/reducers.mli similarity index 100% rename from src/coq/logicutils/hofs/reducers.mli rename to src/coq/logicutils/hofs/impls/reducers.mli diff --git a/src/coq/logicutils/hofs/substitution.ml b/src/coq/logicutils/hofs/impls/substitution.ml similarity index 100% rename from src/coq/logicutils/hofs/substitution.ml rename to src/coq/logicutils/hofs/impls/substitution.ml diff --git a/src/coq/logicutils/hofs/substitution.mli b/src/coq/logicutils/hofs/impls/substitution.mli similarity index 100% rename from src/coq/logicutils/hofs/substitution.mli rename to src/coq/logicutils/hofs/impls/substitution.mli diff --git a/src/coq/logicutils/hofs/typehofs.ml b/src/coq/logicutils/hofs/impls/typehofs.ml similarity index 100% rename from src/coq/logicutils/hofs/typehofs.ml rename to src/coq/logicutils/hofs/impls/typehofs.ml diff --git a/src/coq/logicutils/hofs/typehofs.mli b/src/coq/logicutils/hofs/impls/typehofs.mli similarity index 100% rename from src/coq/logicutils/hofs/typehofs.mli rename to src/coq/logicutils/hofs/impls/typehofs.mli diff --git a/src/coq/logicutils/hofs/zooming.ml b/src/coq/logicutils/hofs/impls/zooming.ml similarity index 100% rename from src/coq/logicutils/hofs/zooming.ml rename to src/coq/logicutils/hofs/impls/zooming.ml diff --git a/src/coq/logicutils/hofs/zooming.mli b/src/coq/logicutils/hofs/impls/zooming.mli similarity index 100% rename from src/coq/logicutils/hofs/zooming.mli rename to src/coq/logicutils/hofs/impls/zooming.mli diff --git a/src/coq/logicutils/inductive/dune b/src/coq/logicutils/inductive/dune new file mode 100644 index 0000000..1484989 --- /dev/null +++ b/src/coq/logicutils/inductive/dune @@ -0,0 +1,10 @@ +(library + (name indutils) + (public_name coq-plugin-lib.inductive) + (libraries + coq-plugin-lib.hofimpls + coq-plugin-lib.debruijn + coq-plugin-lib.termutils + coq-plugin-lib.utilities + coq.kernel + coq.engine)) diff --git a/src/coq/logicutils/inference/dune b/src/coq/logicutils/inference/dune new file mode 100644 index 0000000..65bc89a --- /dev/null +++ b/src/coq/logicutils/inference/dune @@ -0,0 +1,8 @@ +(library + (name inference) + (public_name coq-plugin-lib.inference) + (libraries + coq.pretyping + coq.kernel + coq.engine) + (wrapped false)) diff --git a/src/coq/logicutils/typesandequality/inference.ml b/src/coq/logicutils/inference/inference.ml similarity index 100% rename from src/coq/logicutils/typesandequality/inference.ml rename to src/coq/logicutils/inference/inference.ml diff --git a/src/coq/logicutils/typesandequality/inference.mli b/src/coq/logicutils/inference/inference.mli similarity index 100% rename from src/coq/logicutils/typesandequality/inference.mli rename to src/coq/logicutils/inference/inference.mli diff --git a/src/coq/logicutils/transformation/dune b/src/coq/logicutils/transformation/dune new file mode 100644 index 0000000..ebd6a03 --- /dev/null +++ b/src/coq/logicutils/transformation/dune @@ -0,0 +1,10 @@ +(library + (name transformation) + (public_name coq-plugin-lib.transformation) + (libraries + coq-plugin-lib.hofimpls + coq-plugin-lib.inductive + coq-plugin-lib.contexts + coq.kernel + coq.engine) + (wrapped false)) diff --git a/src/coq/logicutils/typesandequality/dune b/src/coq/logicutils/typesandequality/dune new file mode 100644 index 0000000..22e8fce --- /dev/null +++ b/src/coq/logicutils/typesandequality/dune @@ -0,0 +1,9 @@ +(library + (name typesandequality) + (public_name coq-plugin-lib.typesandequality) + (libraries + coq-plugin-lib.inference + coq-plugin-lib.envs + coq.kernel + coq.engine) + (wrapped false)) diff --git a/src/coq/representationutils/dune b/src/coq/representationutils/dune index 8bc4629..aae2323 100644 --- a/src/coq/representationutils/dune +++ b/src/coq/representationutils/dune @@ -1,3 +1,9 @@ (library (name representationutils) - (public_name coq-plugin-lib.representationutils)) + (public_name coq-plugin-lib.representationutils) + (libraries + coq.vernac + coq.interp + coq.kernel + coq.engine) + (wrapped false)) diff --git a/src/coq/termutils/dune b/src/coq/termutils/dune index c9651db..53d2b07 100644 --- a/src/coq/termutils/dune +++ b/src/coq/termutils/dune @@ -1,3 +1,8 @@ (library (name termutils) - (public_name coq-plugin-lib.termutils)) + (public_name coq-plugin-lib.termutils) + (libraries + coq-plugin-lib.utilities + coq.engine + coq.kernel) + (wrapped false)) diff --git a/src/dune b/src/dune index a20259b..5e6947e 100644 --- a/src/dune +++ b/src/dune @@ -9,7 +9,15 @@ coq-plugin-lib.constants coq-plugin-lib.decompiler coq-plugin-lib.devutils - coq-plugin-lib.logicutils + coq-plugin-lib.envs + coq-plugin-lib.state + coq-plugin-lib.contexts + coq-plugin-lib.inference + coq-plugin-lib.typesandequality + coq-plugin-lib.transformation + coq-plugin-lib.hofs + coq-plugin-lib.hofimpls + coq-plugin-lib.inductive coq-plugin-lib.representationutils coq-plugin-lib.termutils )) diff --git a/src/plibrary.ml4 b/src/plibrary.ml4 index 445a1db..e5410cf 100644 --- a/src/plibrary.ml4 +++ b/src/plibrary.ml4 @@ -27,8 +27,6 @@ open Stdarg open Tacarg open List -open Py -open Serapi_protocol (* --- Commands --- *) diff --git a/src/utilities/dune b/src/utilities/dune index 84f1ef8..5bb1081 100644 --- a/src/utilities/dune +++ b/src/utilities/dune @@ -1,3 +1,6 @@ (library (name utilities) - (public_name coq-plugin-lib.utilities)) + (public_name coq-plugin-lib.utilities) + (libraries + coq.lib) + (wrapped false)) From 37ffabc297f6639541e0fab14cf1f675c45dc8ca Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Wed, 8 Sep 2021 13:14:28 -0500 Subject: [PATCH 19/39] Attempt to build theory with dune --- dune-project | 4 ++-- src/dune | 5 +++-- theories/dune | 8 ++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 theories/dune diff --git a/dune-project b/dune-project index 777fbba..3565c82 100644 --- a/dune-project +++ b/dune-project @@ -1,3 +1,3 @@ -(lang dune 1.10) -(using coq 0.1) +(lang dune 2.8.3) +(using coq 0.2) (name coq-plugin-lib) diff --git a/src/dune b/src/dune index 5e6947e..56f03a6 100644 --- a/src/dune +++ b/src/dune @@ -1,8 +1,9 @@ (library - (name coq_plugin_lib) + (name plib) (public_name coq-plugin-lib.plugin) (synopsis "Coq Plugin Lib") - (flags :standard -w -27) ; CoqPP codes requires this + (flags :standard -w -27 -warn-error -A) ; CoqPP codes requires this + (modules ("plibrary")) (libraries coq.vernac ; needed for vernac extend coq-plugin-lib.utilities diff --git a/theories/dune b/theories/dune new file mode 100644 index 0000000..c0cfe4c --- /dev/null +++ b/theories/dune @@ -0,0 +1,8 @@ +(coq.theory + (name CoqPluginLib) + (package coq-plugin-lib) + (flags -q -noinit) + (libraries + coq-plugin-lib.plugin + ) +) From 7099ed497e6c10c39a44f4e13348a7c2b1271afd Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Wed, 8 Sep 2021 13:26:31 -0500 Subject: [PATCH 20/39] use older dune --- build.sh | 1 + coq-plugin-lib.opam | 2 +- dune-project | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 7afe3ec..8311954 100755 --- a/build.sh +++ b/build.sh @@ -1 +1,2 @@ +opam pin dune 2.7.1 dune build diff --git a/coq-plugin-lib.opam b/coq-plugin-lib.opam index 45fe339..7577de2 100644 --- a/coq-plugin-lib.opam +++ b/coq-plugin-lib.opam @@ -13,7 +13,7 @@ doc: "https://github.com/uwplse/coq-plugin-lib" depends: [ "ocaml" { = "4.07.1+flambda" } "coq" { = "8.9.1" } - "dune" { build & >= "1.9.0" } + "dune" { build & >= "1.9.0" & <= "2.7.1" } ] build: [ "dune" "build" "-p" name "-j" jobs ] diff --git a/dune-project b/dune-project index 3565c82..709e0e9 100644 --- a/dune-project +++ b/dune-project @@ -1,3 +1,3 @@ -(lang dune 2.8.3) +(lang dune 2.7.1) (using coq 0.2) (name coq-plugin-lib) From 2a57d2653c6f1e6daf2a9a03f774e23c9c96ff20 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Wed, 8 Sep 2021 15:27:58 -0500 Subject: [PATCH 21/39] annoying things --- src/coq/constants/.merlin | 32 +++++++++ src/coq/decompiler/.merlin | 72 +++++++++++++++++++++ src/coq/devutils/.merlin | 70 ++++++++++++++++++++ src/coq/dune | 20 ++++++ src/coq/logicutils/contexts/.merlin | 68 +++++++++++++++++++ src/coq/logicutils/contexts/envs/.merlin | 52 +++++++++++++++ src/coq/logicutils/contexts/state/.merlin | 30 +++++++++ src/coq/logicutils/debruijn/.merlin | 58 +++++++++++++++++ src/coq/logicutils/hofs/.merlin | 56 ++++++++++++++++ src/coq/logicutils/hofs/impls/.merlin | 64 ++++++++++++++++++ src/coq/logicutils/inductive/.merlin | 66 +++++++++++++++++++ src/coq/logicutils/inductive/dune | 5 +- src/coq/logicutils/inference/.merlin | 26 ++++++++ src/coq/logicutils/transformation/.merlin | 70 ++++++++++++++++++++ src/coq/logicutils/typesandequality/.merlin | 54 ++++++++++++++++ src/coq/representationutils/.merlin | 40 ++++++++++++ src/coq/termutils/.merlin | 26 ++++++++ src/dune | 2 + theories/Plib.v | 22 +++++-- theories/dune | 17 +++++ 20 files changed, 844 insertions(+), 6 deletions(-) create mode 100644 src/coq/constants/.merlin create mode 100644 src/coq/decompiler/.merlin create mode 100644 src/coq/devutils/.merlin create mode 100644 src/coq/dune create mode 100644 src/coq/logicutils/contexts/.merlin create mode 100644 src/coq/logicutils/contexts/envs/.merlin create mode 100644 src/coq/logicutils/contexts/state/.merlin create mode 100644 src/coq/logicutils/debruijn/.merlin create mode 100644 src/coq/logicutils/hofs/.merlin create mode 100644 src/coq/logicutils/hofs/impls/.merlin create mode 100644 src/coq/logicutils/inductive/.merlin create mode 100644 src/coq/logicutils/inference/.merlin create mode 100644 src/coq/logicutils/transformation/.merlin create mode 100644 src/coq/logicutils/typesandequality/.merlin create mode 100644 src/coq/representationutils/.merlin create mode 100644 src/coq/termutils/.merlin diff --git a/src/coq/constants/.merlin b/src/coq/constants/.merlin new file mode 100644 index 0000000..e3b8305 --- /dev/null +++ b/src/coq/constants/.merlin @@ -0,0 +1,32 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../_build/default/src/coq/constants/.constants.objs/byte +B ../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../_build/default/src/coq/termutils/.termutils.objs/byte +B ../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S . +S ../logicutils/inference +S ../termutils +S ../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/decompiler/.merlin b/src/coq/decompiler/.merlin new file mode 100644 index 0000000..9108183 --- /dev/null +++ b/src/coq/decompiler/.merlin @@ -0,0 +1,72 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/stm +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../_build/default/src/coq/constants/.constants.objs/byte +B ../../../_build/default/src/coq/decompiler/.decompiler.objs/byte +B ../../../_build/default/src/coq/devutils/.devutils.objs/byte +B ../../../_build/default/src/coq/logicutils/contexts/.contexts.objs/byte +B ../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte +B ../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte +B ../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte +B ../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte +B ../../../_build/default/src/coq/logicutils/inductive/.inductive.objs/byte +B ../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte +B ../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +B ../../../_build/default/src/coq/termutils/.termutils.objs/byte +B ../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/stm +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S ../constants +S . +S ../devutils +S ../logicutils/contexts +S ../logicutils/contexts/envs +S ../logicutils/contexts/state +S ../logicutils/debruijn +S ../logicutils/hofs +S ../logicutils/hofs/impls +S ../logicutils/inductive +S ../logicutils/inference +S ../logicutils/typesandequality +S ../representationutils +S ../termutils +S ../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/devutils/.merlin b/src/coq/devutils/.merlin new file mode 100644 index 0000000..5afe5d8 --- /dev/null +++ b/src/coq/devutils/.merlin @@ -0,0 +1,70 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/stm +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../_build/default/src/coq/constants/.constants.objs/byte +B ../../../_build/default/src/coq/devutils/.devutils.objs/byte +B ../../../_build/default/src/coq/logicutils/contexts/.contexts.objs/byte +B ../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte +B ../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte +B ../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte +B ../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte +B ../../../_build/default/src/coq/logicutils/inductive/.inductive.objs/byte +B ../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte +B ../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +B ../../../_build/default/src/coq/termutils/.termutils.objs/byte +B ../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/stm +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S ../constants +S . +S ../logicutils/contexts +S ../logicutils/contexts/envs +S ../logicutils/contexts/state +S ../logicutils/debruijn +S ../logicutils/hofs +S ../logicutils/hofs/impls +S ../logicutils/inductive +S ../logicutils/inference +S ../logicutils/typesandequality +S ../representationutils +S ../termutils +S ../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/dune b/src/coq/dune new file mode 100644 index 0000000..fa885ff --- /dev/null +++ b/src/coq/dune @@ -0,0 +1,20 @@ +(library + (name coq) + (public_name coq-plugin-lib.coq) + (libraries + coq-plugin-lib.constants + coq-plugin-lib.decompiler + coq-plugin-lib.devutils + coq-plugin-lib.envs + coq-plugin-lib.state + coq-plugin-lib.contexts + coq-plugin-lib.inference + coq-plugin-lib.typesandequality + coq-plugin-lib.transformation + coq-plugin-lib.hofs + coq-plugin-lib.hofimpls + coq-plugin-lib.inductive + coq-plugin-lib.representationutils + coq-plugin-lib.termutils + coq.kernel) + (wrapped false)) diff --git a/src/coq/logicutils/contexts/.merlin b/src/coq/logicutils/contexts/.merlin new file mode 100644 index 0000000..852cd1f --- /dev/null +++ b/src/coq/logicutils/contexts/.merlin @@ -0,0 +1,68 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/stm +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../../_build/default/src/coq/constants/.constants.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/.contexts.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte +B ../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte +B ../../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte +B ../../../../_build/default/src/coq/logicutils/inductive/.inductive.objs/byte +B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte +B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +B ../../../../_build/default/src/coq/termutils/.termutils.objs/byte +B ../../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/stm +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S ../../constants +S . +S envs +S state +S ../debruijn +S ../hofs +S ../hofs/impls +S ../inductive +S ../inference +S ../typesandequality +S ../../representationutils +S ../../termutils +S ../../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/contexts/envs/.merlin b/src/coq/logicutils/contexts/envs/.merlin new file mode 100644 index 0000000..4959868 --- /dev/null +++ b/src/coq/logicutils/contexts/envs/.merlin @@ -0,0 +1,52 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/stm +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte +B ../../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +B ../../../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/stm +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S . +S ../state +S ../../inference +S ../../../representationutils +S ../../../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/contexts/state/.merlin b/src/coq/logicutils/contexts/state/.merlin new file mode 100644 index 0000000..8226e53 --- /dev/null +++ b/src/coq/logicutils/contexts/state/.merlin @@ -0,0 +1,30 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S . +S ../../../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/debruijn/.merlin b/src/coq/logicutils/debruijn/.merlin new file mode 100644 index 0000000..367f697 --- /dev/null +++ b/src/coq/logicutils/debruijn/.merlin @@ -0,0 +1,58 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/stm +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte +B ../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte +B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte +B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +B ../../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/stm +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S ../contexts/envs +S ../contexts/state +S . +S ../hofs +S ../inference +S ../typesandequality +S ../../representationutils +S ../../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/hofs/.merlin b/src/coq/logicutils/hofs/.merlin new file mode 100644 index 0000000..756dee0 --- /dev/null +++ b/src/coq/logicutils/hofs/.merlin @@ -0,0 +1,56 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/stm +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte +B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte +B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +B ../../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/stm +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S ../contexts/envs +S ../contexts/state +S . +S ../inference +S ../typesandequality +S ../../representationutils +S ../../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/hofs/impls/.merlin b/src/coq/logicutils/hofs/impls/.merlin new file mode 100644 index 0000000..8f31b42 --- /dev/null +++ b/src/coq/logicutils/hofs/impls/.merlin @@ -0,0 +1,64 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/stm +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../../../_build/default/src/coq/constants/.constants.objs/byte +B ../../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte +B ../../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte +B ../../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte +B ../../../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte +B ../../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte +B ../../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +B ../../../../../_build/default/src/coq/termutils/.termutils.objs/byte +B ../../../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/stm +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S ../../../constants +S ../../contexts/envs +S ../../contexts/state +S ../../debruijn +S .. +S . +S ../../inference +S ../../typesandequality +S ../../../representationutils +S ../../../termutils +S ../../../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/inductive/.merlin b/src/coq/logicutils/inductive/.merlin new file mode 100644 index 0000000..38a0139 --- /dev/null +++ b/src/coq/logicutils/inductive/.merlin @@ -0,0 +1,66 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/stm +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../../_build/default/src/coq/constants/.constants.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte +B ../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte +B ../../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte +B ../../../../_build/default/src/coq/logicutils/inductive/.inductive.objs/byte +B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte +B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +B ../../../../_build/default/src/coq/termutils/.termutils.objs/byte +B ../../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/stm +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S ../../constants +S ../contexts/envs +S ../contexts/state +S ../debruijn +S ../hofs +S ../hofs/impls +S . +S ../inference +S ../typesandequality +S ../../representationutils +S ../../termutils +S ../../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/inductive/dune b/src/coq/logicutils/inductive/dune index 1484989..750663b 100644 --- a/src/coq/logicutils/inductive/dune +++ b/src/coq/logicutils/inductive/dune @@ -1,5 +1,5 @@ (library - (name indutils) + (name inductive) (public_name coq-plugin-lib.inductive) (libraries coq-plugin-lib.hofimpls @@ -7,4 +7,5 @@ coq-plugin-lib.termutils coq-plugin-lib.utilities coq.kernel - coq.engine)) + coq.engine) + (wrapped false)) diff --git a/src/coq/logicutils/inference/.merlin b/src/coq/logicutils/inference/.merlin new file mode 100644 index 0000000..b0fe410 --- /dev/null +++ b/src/coq/logicutils/inference/.merlin @@ -0,0 +1,26 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S . +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/transformation/.merlin b/src/coq/logicutils/transformation/.merlin new file mode 100644 index 0000000..21e2be6 --- /dev/null +++ b/src/coq/logicutils/transformation/.merlin @@ -0,0 +1,70 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/stm +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../../_build/default/src/coq/constants/.constants.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/.contexts.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte +B ../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte +B ../../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte +B ../../../../_build/default/src/coq/logicutils/inductive/.inductive.objs/byte +B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../../_build/default/src/coq/logicutils/transformation/.transformation.objs/byte +B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte +B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +B ../../../../_build/default/src/coq/termutils/.termutils.objs/byte +B ../../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/stm +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S ../../constants +S ../contexts +S ../contexts/envs +S ../contexts/state +S ../debruijn +S ../hofs +S ../hofs/impls +S ../inductive +S ../inference +S . +S ../typesandequality +S ../../representationutils +S ../../termutils +S ../../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/typesandequality/.merlin b/src/coq/logicutils/typesandequality/.merlin new file mode 100644 index 0000000..066802f --- /dev/null +++ b/src/coq/logicutils/typesandequality/.merlin @@ -0,0 +1,54 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/stm +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte +B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte +B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte +B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte +B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +B ../../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/stm +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S ../contexts/envs +S ../contexts/state +S ../inference +S . +S ../../representationutils +S ../../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/representationutils/.merlin b/src/coq/representationutils/.merlin new file mode 100644 index 0000000..e5a7c02 --- /dev/null +++ b/src/coq/representationutils/.merlin @@ -0,0 +1,40 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/camlp5 +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/interp +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +B /home/talia/.opam/4.07.1+flambda/lib/coq/printing +B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../_build/default/src/coq/representationutils/.representationutils.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/camlp5 +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/interp +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing +S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping +S /home/talia/.opam/4.07.1+flambda/lib/coq/printing +S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs +S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics +S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S . +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/termutils/.merlin b/src/coq/termutils/.merlin new file mode 100644 index 0000000..47fd2c8 --- /dev/null +++ b/src/coq/termutils/.merlin @@ -0,0 +1,26 @@ +EXCLUDE_QUERY_DIR +B /home/talia/.opam/4.07.1+flambda/lib/coq/clib +B /home/talia/.opam/4.07.1+flambda/lib/coq/config +B /home/talia/.opam/4.07.1+flambda/lib/coq/engine +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +B /home/talia/.opam/4.07.1+flambda/lib/coq/lib +B /home/talia/.opam/4.07.1+flambda/lib/coq/library +B /home/talia/.opam/4.07.1+flambda/lib/num +B /home/talia/.opam/4.07.1+flambda/lib/ocaml +B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +B ../../../_build/default/src/coq/termutils/.termutils.objs/byte +B ../../../_build/default/src/utilities/.utilities.objs/byte +S /home/talia/.opam/4.07.1+flambda/lib/coq/clib +S /home/talia/.opam/4.07.1+flambda/lib/coq/config +S /home/talia/.opam/4.07.1+flambda/lib/coq/engine +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel +S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun +S /home/talia/.opam/4.07.1+flambda/lib/coq/lib +S /home/talia/.opam/4.07.1+flambda/lib/coq/library +S /home/talia/.opam/4.07.1+flambda/lib/num +S /home/talia/.opam/4.07.1+flambda/lib/ocaml +S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads +S . +S ../../utilities +FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/dune b/src/dune index 56f03a6..9525005 100644 --- a/src/dune +++ b/src/dune @@ -7,6 +7,8 @@ (libraries coq.vernac ; needed for vernac extend coq-plugin-lib.utilities + coq-plugin-lib.coq + coq-plugin-lib.debruijn coq-plugin-lib.constants coq-plugin-lib.decompiler coq-plugin-lib.devutils diff --git a/theories/Plib.v b/theories/Plib.v index fe50713..312fb1c 100644 --- a/theories/Plib.v +++ b/theories/Plib.v @@ -1,6 +1,20 @@ +Declare ML Module "utilities". +Declare ML Module "coq". +Declare ML Module "termutils". +Declare ML Module "inference". +Declare ML Module "constants". +Declare ML Module "representationutils". +Declare ML Module "state". +Declare ML Module "envs". +Declare ML Module "devutils". +Declare ML Module "hofs". +Declare ML Module "typesandequality". +Declare ML Module "debruijn". +Declare ML Module "hofimpls". +Declare ML Module "inductive". +Declare ML Module "contexts". +Declare ML Module "transformation". +Declare ML Module "ltac_plugin". +Declare ML Module "decompiler". Declare ML Module "plib". -(* Add ML Path "/Users/emilyfirst/.opam/4.07.1+flambda/lib/coq-serapi/serlib". *) -(* Add ML Path "/Users/emilyfirst/.opam/4.07.1+flambda/lib/pyml". *) - -(* Declare ML Module "serlib". *) diff --git a/theories/dune b/theories/dune index c0cfe4c..bbfff4f 100644 --- a/theories/dune +++ b/theories/dune @@ -3,6 +3,23 @@ (package coq-plugin-lib) (flags -q -noinit) (libraries + coq-plugin-lib.utilities + coq-plugin-lib.coq + coq-plugin-lib.debruijn + coq-plugin-lib.constants + coq-plugin-lib.decompiler + coq-plugin-lib.devutils + coq-plugin-lib.envs + coq-plugin-lib.state + coq-plugin-lib.contexts + coq-plugin-lib.inference + coq-plugin-lib.typesandequality + coq-plugin-lib.transformation + coq-plugin-lib.hofs + coq-plugin-lib.hofimpls + coq-plugin-lib.inductive + coq-plugin-lib.representationutils + coq-plugin-lib.termutils coq-plugin-lib.plugin ) ) From bdfa573de34d77bc0763b5d0a83cc853d3bba4b8 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Wed, 8 Sep 2021 16:02:21 -0500 Subject: [PATCH 22/39] idk --- build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sh b/build.sh index 8311954..739f23d 100755 --- a/build.sh +++ b/build.sh @@ -1,2 +1,3 @@ opam pin dune 2.7.1 +dune clean dune build From 3fb69defb7f4e771acc84de5d696b832d5c2001a Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Thu, 16 Sep 2021 11:12:16 -0500 Subject: [PATCH 23/39] Emilio is amazing --- build.sh | 3 ++- src/dune | 11 +++++++++++ src/plibrary.ml4 | 2 ++ theories/Plib.v | 18 +++++++++++++++--- theories/dune | 22 +--------------------- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/build.sh b/build.sh index 739f23d..f65751b 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,4 @@ opam pin dune 2.7.1 dune clean -dune build +dune build @all +dune install diff --git a/src/dune b/src/dune index 9525005..a1051ea 100644 --- a/src/dune +++ b/src/dune @@ -6,6 +6,7 @@ (modules ("plibrary")) (libraries coq.vernac ; needed for vernac extend + coq-serapi.serlib coq-plugin-lib.utilities coq-plugin-lib.coq coq-plugin-lib.debruijn @@ -25,6 +26,16 @@ coq-plugin-lib.termutils )) +(rule + (targets plib_full_plugin.cmxs) + (action (run %{ocamlopt} -shared -linkall -o %{targets}))) + +(install + (section lib_root) + (package coq-plugin-lib) + (files + (plib_full_plugin.cmxs as coq/user-contrib/plib_full_plugin.cmxs))) + (rule (targets plibrary.ml) (deps (:pp-file plibrary.ml4) ) diff --git a/src/plibrary.ml4 b/src/plibrary.ml4 index e5410cf..ed3c359 100644 --- a/src/plibrary.ml4 +++ b/src/plibrary.ml4 @@ -26,6 +26,8 @@ open Class_tactics open Stdarg open Tacarg +open Ser_names + open List (* --- Commands --- *) diff --git a/theories/Plib.v b/theories/Plib.v index 312fb1c..be8bd00 100644 --- a/theories/Plib.v +++ b/theories/Plib.v @@ -1,4 +1,5 @@ -Declare ML Module "utilities". +(* Dependencies for our library *) +(*Declare ML Module "utilities". Declare ML Module "coq". Declare ML Module "termutils". Declare ML Module "inference". @@ -15,6 +16,17 @@ Declare ML Module "inductive". Declare ML Module "contexts". Declare ML Module "transformation". Declare ML Module "ltac_plugin". -Declare ML Module "decompiler". -Declare ML Module "plib". +Declare ML Module "decompiler".*) + +(* Dependencies for SerAPI *) +(*Declare ML Module "sexplib0". +Declare ML Module "ppx_sexp_conv_lib". +Declare ML Module "bigarray". +Declare ML Module "caml". +Declare ML Module "parsexp". +Declare ML Module "sexplib". +Declare ML Module "serlib".*) + +(* Our library *) +Declare ML Module "plib_full_plugin". diff --git a/theories/dune b/theories/dune index bbfff4f..e32b588 100644 --- a/theories/dune +++ b/theories/dune @@ -1,25 +1,5 @@ (coq.theory (name CoqPluginLib) (package coq-plugin-lib) - (flags -q -noinit) - (libraries - coq-plugin-lib.utilities - coq-plugin-lib.coq - coq-plugin-lib.debruijn - coq-plugin-lib.constants - coq-plugin-lib.decompiler - coq-plugin-lib.devutils - coq-plugin-lib.envs - coq-plugin-lib.state - coq-plugin-lib.contexts - coq-plugin-lib.inference - coq-plugin-lib.typesandequality - coq-plugin-lib.transformation - coq-plugin-lib.hofs - coq-plugin-lib.hofimpls - coq-plugin-lib.inductive - coq-plugin-lib.representationutils - coq-plugin-lib.termutils - coq-plugin-lib.plugin - ) + (flags -q -noinit -I ./src) ) From e1f7bf4f843d6767aff93472abbf4491b183224a Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Thu, 16 Sep 2021 11:17:28 -0500 Subject: [PATCH 24/39] Remove comments --- theories/Plib.v | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/theories/Plib.v b/theories/Plib.v index be8bd00..9ead491 100644 --- a/theories/Plib.v +++ b/theories/Plib.v @@ -1,32 +1,3 @@ -(* Dependencies for our library *) -(*Declare ML Module "utilities". -Declare ML Module "coq". -Declare ML Module "termutils". -Declare ML Module "inference". -Declare ML Module "constants". -Declare ML Module "representationutils". -Declare ML Module "state". -Declare ML Module "envs". -Declare ML Module "devutils". -Declare ML Module "hofs". -Declare ML Module "typesandequality". -Declare ML Module "debruijn". -Declare ML Module "hofimpls". -Declare ML Module "inductive". -Declare ML Module "contexts". -Declare ML Module "transformation". -Declare ML Module "ltac_plugin". -Declare ML Module "decompiler".*) - -(* Dependencies for SerAPI *) -(*Declare ML Module "sexplib0". -Declare ML Module "ppx_sexp_conv_lib". -Declare ML Module "bigarray". -Declare ML Module "caml". -Declare ML Module "parsexp". -Declare ML Module "sexplib". -Declare ML Module "serlib".*) - -(* Our library *) +(* Uses the ad-hoc .cmxs file *) Declare ML Module "plib_full_plugin". From a9fd906dbbf9adb553e627b4da5354aa8937fc86 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Thu, 16 Sep 2021 11:27:17 -0500 Subject: [PATCH 25/39] Doesn't need Makefile --- Makefile | 802 ------------------------------------------------------- 1 file changed, 802 deletions(-) delete mode 100644 Makefile diff --git a/Makefile b/Makefile deleted file mode 100644 index 3d05fd8..0000000 --- a/Makefile +++ /dev/null @@ -1,802 +0,0 @@ -############################################################################### -## v # The Coq Proof Assistant ## -## /dev/null 2>/dev/null; echo $$?)) -STDTIME?=command time -f $(TIMEFMT) -else -ifeq (0,$(shell gtime -f $(TIMEFMT) true >/dev/null 2>/dev/null; echo $$?)) -STDTIME?=gtime -f $(TIMEFMT) -else -STDTIME?=command time -endif -endif -else -STDTIME?=command time -f $(TIMEFMT) -endif - -# Coq binaries -COQC ?= "$(COQBIN)coqc" -COQTOP ?= "$(COQBIN)coqtop" -COQCHK ?= "$(COQBIN)coqchk" -COQDEP ?= "$(COQBIN)coqdep" -COQDOC ?= "$(COQBIN)coqdoc" -COQMKFILE ?= "$(COQBIN)coq_makefile" - -# Timing scripts -COQMAKE_ONE_TIME_FILE ?= "$(COQLIB)/tools/make-one-time-file.py" -COQMAKE_BOTH_TIME_FILES ?= "$(COQLIB)/tools/make-both-time-files.py" -COQMAKE_BOTH_SINGLE_TIMING_FILES ?= "$(COQLIB)/tools/make-both-single-timing-files.py" -BEFORE ?= -AFTER ?= - -# FIXME this should be generated by Coq (modules already linked by Coq) -CAMLDONTLINK=camlp5.gramlib,unix,str - -# OCaml binaries -CAMLC ?= "$(OCAMLFIND)" ocamlc -c -CAMLOPTC ?= "$(OCAMLFIND)" opt -c -CAMLLINK ?= "$(OCAMLFIND)" ocamlc -linkpkg -dontlink $(CAMLDONTLINK) -CAMLOPTLINK ?= "$(OCAMLFIND)" opt -linkpkg -dontlink $(CAMLDONTLINK) -CAMLDOC ?= "$(OCAMLFIND)" ocamldoc -CAMLDEP ?= "$(OCAMLFIND)" ocamldep -slash -ml-synonym .ml4 -ml-synonym .mlpack - -# DESTDIR is prepended to all installation paths -DESTDIR ?= - -# Debug builds, typically -g to OCaml, -debug to Coq. -CAMLDEBUG ?= -COQDEBUG ?= - -# Extra packages to be linked in (as in findlib -package) -CAMLPKGS ?= - -# Option for making timing files -TIMING?= -# Option for changing sorting of timing output file -TIMING_SORT_BY ?= auto -# Output file names for timed builds -TIME_OF_BUILD_FILE ?= time-of-build.log -TIME_OF_BUILD_BEFORE_FILE ?= time-of-build-before.log -TIME_OF_BUILD_AFTER_FILE ?= time-of-build-after.log -TIME_OF_PRETTY_BUILD_FILE ?= time-of-build-pretty.log -TIME_OF_PRETTY_BOTH_BUILD_FILE ?= time-of-build-both.log -TIME_OF_PRETTY_BUILD_EXTRA_FILES ?= - # also output to the command line - -########## End of parameters ################################################## -# What follows may be relevant to you only if you need to -# extend this Makefile. If so, look for 'Extension point' here and -# put in Makefile.local double colon rules accordingly. -# E.g. to perform some work after the all target completes you can write -# -# post-all:: -# echo "All done!" -# -# in Makefile.local -# -############################################################################### - - - - -# Flags ####################################################################### -# -# We define a bunch of variables combining the parameters. -# To add additional flags to coq, coqchk or coqdoc, set the -# {COQ,COQCHK,COQDOC}EXTRAFLAGS variable to whatever you want to add. -# To overwrite the default choice and set your own flags entirely, set the -# {COQ,COQCHK,COQDOC}FLAGS variable. - -SHOW := $(if $(VERBOSE),@true "",@echo "") -HIDE := $(if $(VERBOSE),,@) - -TIMER=$(if $(TIMED), $(STDTIME), $(TIMECMD)) - -OPT?= - -# The DYNOBJ and DYNLIB variables are used by "coqdep -dyndep var" in .v.d -ifeq '$(OPT)' '-byte' -USEBYTE:=true -DYNOBJ:=.cma -DYNLIB:=.cma -else -USEBYTE:= -DYNOBJ:=.cmxs -DYNLIB:=.cmxs -endif - -# these variables are meant to be overriden if you want to add *extra* flags -COQEXTRAFLAGS?= -COQCHKEXTRAFLAGS?= -COQDOCEXTRAFLAGS?= - -# these flags do NOT contain the libraries, to make them easier to overwrite -COQFLAGS?=-q $(OPT) $(OTHERFLAGS) $(COQEXTRAFLAGS) -COQCHKFLAGS?=-silent -o $(COQCHKEXTRAFLAGS) -COQDOCFLAGS?=-interpolate -utf8 $(COQDOCEXTRAFLAGS) - -COQDOCLIBS?=$(COQLIBS_NOML) - -# The version of Coq being run and the version of coq_makefile that -# generated this makefile -COQ_VERSION:=$(shell $(COQC) --print-version | cut -d " " -f 1) -COQMAKEFILE_VERSION:=8.9.1 - -COQSRCLIBS?= $(foreach d,$(COQ_SRC_SUBDIRS), -I "$(COQLIB)$(d)") - -CAMLFLAGS+=$(OCAMLLIBS) $(COQSRCLIBS) -I $(CAMLP5LIB) - -# ocamldoc fails with unknown argument otherwise -CAMLDOCFLAGS=$(filter-out -annot, $(filter-out -bin-annot, $(CAMLFLAGS))) - -# FIXME This should be generated by Coq -GRAMMARS:=grammar.cma -CAMLP5EXTEND=pa_extend.cmo q_MLast.cmo pa_macro.cmo - -CAMLLIB:=$(shell "$(OCAMLFIND)" printconf stdlib 2> /dev/null) -ifeq (,$(CAMLLIB)) -PP=$(error "Cannot find the 'ocamlfind' binary used to build Coq ($(OCAMLFIND)). Pre-compiled binary packages of Coq do not support compiling plugins this way. Please download the sources of Coq and run the Windows build script.") -else -PP:=-pp '$(CAMLP5O) -I $(CAMLLIB) -I "$(COQLIB)/grammar" $(CAMLP5EXTEND) $(GRAMMARS) $(CAMLP5OPTIONS) -impl' -endif - -ifneq (,$(TIMING)) -TIMING_ARG=-time -ifeq (after,$(TIMING)) -TIMING_EXT=after-timing -else -ifeq (before,$(TIMING)) -TIMING_EXT=before-timing -else -TIMING_EXT=timing -endif -endif -else -TIMING_ARG= -endif - -# Retro compatibility (DESTDIR is standard on Unix, DSTROOT is not) -ifdef DSTROOT -DESTDIR := $(DSTROOT) -endif - -concat_path = $(if $(1),$(1)/$(if $(COQMF_WINDRIVE),$(subst $(COQMF_WINDRIVE),/,$(2)),$(2)),$(2)) - -COQLIBINSTALL = $(call concat_path,$(DESTDIR),$(COQLIB)user-contrib) -COQDOCINSTALL = $(call concat_path,$(DESTDIR),$(DOCDIR)user-contrib) -COQTOPINSTALL = $(call concat_path,$(DESTDIR),$(COQLIB)toploop) - -# Files ####################################################################### -# -# We here define a bunch of variables about the files being part of the -# Coq project in order to ease the writing of build target and build rules - -VDFILE := .coqdeps - -ALLSRCFILES := \ - $(ML4FILES) \ - $(MLFILES) \ - $(MLPACKFILES) \ - $(MLLIBFILES) \ - $(MLIFILES) - -# helpers -vo_to_obj = $(addsuffix .o,\ - $(filter-out Warning: Error:,\ - $(shell $(COQTOP) -q -noinit -batch -quiet -print-mod-uid $(1)))) -strip_dotslash = $(patsubst ./%,%,$(1)) -VO = vo - -VOFILES = $(VFILES:.v=.$(VO)) -GLOBFILES = $(VFILES:.v=.glob) -HTMLFILES = $(VFILES:.v=.html) -GHTMLFILES = $(VFILES:.v=.g.html) -BEAUTYFILES = $(addsuffix .beautified,$(VFILES)) -TEXFILES = $(VFILES:.v=.tex) -GTEXFILES = $(VFILES:.v=.g.tex) -CMOFILES = \ - $(ML4FILES:.ml4=.cmo) \ - $(MLFILES:.ml=.cmo) \ - $(MLPACKFILES:.mlpack=.cmo) -CMXFILES = $(CMOFILES:.cmo=.cmx) -OFILES = $(CMXFILES:.cmx=.o) -CMAFILES = $(MLLIBFILES:.mllib=.cma) $(MLPACKFILES:.mlpack=.cma) -CMXAFILES = $(CMAFILES:.cma=.cmxa) -CMIFILES = \ - $(CMOFILES:.cmo=.cmi) \ - $(MLIFILES:.mli=.cmi) -# the /if/ is because old _CoqProject did not list a .ml(pack|lib) but just -# a .ml4 file -CMXSFILES = \ - $(MLPACKFILES:.mlpack=.cmxs) \ - $(CMXAFILES:.cmxa=.cmxs) \ - $(if $(MLPACKFILES)$(CMXAFILES),,\ - $(ML4FILES:.ml4=.cmxs) $(MLFILES:.ml=.cmxs)) - -# files that are packed into a plugin (no extension) -PACKEDFILES = \ - $(call strip_dotslash, \ - $(foreach lib, \ - $(call strip_dotslash, \ - $(MLPACKFILES:.mlpack=_MLPACK_DEPENDENCIES)),$($(lib)))) -# files that are archived into a .cma (mllib) -LIBEDFILES = \ - $(call strip_dotslash, \ - $(foreach lib, \ - $(call strip_dotslash, \ - $(MLLIBFILES:.mllib=_MLLIB_DEPENDENCIES)),$($(lib)))) -CMIFILESTOINSTALL = $(filter-out $(addsuffix .cmi,$(PACKEDFILES)),$(CMIFILES)) -CMOFILESTOINSTALL = $(filter-out $(addsuffix .cmo,$(PACKEDFILES)),$(CMOFILES)) -OBJFILES = $(call vo_to_obj,$(VOFILES)) -ALLNATIVEFILES = \ - $(OBJFILES:.o=.cmi) \ - $(OBJFILES:.o=.cmx) \ - $(OBJFILES:.o=.cmxs) -# trick: wildcard filters out non-existing files, so that `install` doesn't show -# warnings and `clean` doesn't pass to rm a list of files that is too long for -# the shell. -NATIVEFILES = $(wildcard $(ALLNATIVEFILES)) -FILESTOINSTALL = \ - $(VOFILES) \ - $(VFILES) \ - $(GLOBFILES) \ - $(NATIVEFILES) \ - $(CMIFILESTOINSTALL) -BYTEFILESTOINSTALL = \ - $(CMOFILESTOINSTALL) \ - $(CMAFILES) -ifeq '$(HASNATDYNLINK)' 'true' -DO_NATDYNLINK = yes -FILESTOINSTALL += $(CMXSFILES) $(CMXAFILES) $(CMOFILESTOINSTALL:.cmo=.cmx) -else -DO_NATDYNLINK = -endif - -ALLDFILES = $(addsuffix .d,$(ALLSRCFILES) $(VDFILE)) - -# Compilation targets ######################################################### - -all: - $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" pre-all - $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" real-all - $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" post-all -.PHONY: all - -all.timing.diff: - $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" pre-all - $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" real-all.timing.diff TIME_OF_PRETTY_BUILD_EXTRA_FILES="" - $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" post-all -.PHONY: all.timing.diff - -make-pretty-timed-before:: TIME_OF_BUILD_FILE=$(TIME_OF_BUILD_BEFORE_FILE) -make-pretty-timed-after:: TIME_OF_BUILD_FILE=$(TIME_OF_BUILD_AFTER_FILE) -make-pretty-timed make-pretty-timed-before make-pretty-timed-after:: - $(HIDE)rm -f pretty-timed-success.ok - $(HIDE)($(MAKE) --no-print-directory -f "$(PARENT)" $(TGTS) TIMED=1 2>&1 && touch pretty-timed-success.ok) | tee -a $(TIME_OF_BUILD_FILE) - $(HIDE)rm pretty-timed-success.ok # must not be -f; must fail if the touch failed -print-pretty-timed:: - $(HIDE)$(COQMAKE_ONE_TIME_FILE) $(TIME_OF_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES) -print-pretty-timed-diff:: - $(HIDE)$(COQMAKE_BOTH_TIME_FILES) --sort-by=$(TIMING_SORT_BY) $(TIME_OF_BUILD_AFTER_FILE) $(TIME_OF_BUILD_BEFORE_FILE) $(TIME_OF_PRETTY_BOTH_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES) -ifeq (,$(BEFORE)) -print-pretty-single-time-diff:: - @echo 'Error: Usage: $(MAKE) print-pretty-single-time-diff AFTER=path/to/file.v.after-timing BEFORE=path/to/file.v.before-timing' - $(HIDE)false -else -ifeq (,$(AFTER)) -print-pretty-single-time-diff:: - @echo 'Error: Usage: $(MAKE) print-pretty-single-time-diff AFTER=path/to/file.v.after-timing BEFORE=path/to/file.v.before-timing' - $(HIDE)false -else -print-pretty-single-time-diff:: - $(HIDE)$(COQMAKE_BOTH_SINGLE_TIMING_FILES) --sort-by=$(TIMING_SORT_BY) $(AFTER) $(BEFORE) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES) -endif -endif -pretty-timed: - $(HIDE)$(MAKE) --no-print-directory -f "$(PARENT)" make-pretty-timed - $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" print-pretty-timed -.PHONY: pretty-timed make-pretty-timed make-pretty-timed-before make-pretty-timed-after print-pretty-timed print-pretty-timed-diff print-pretty-single-time-diff - -# Extension points for actions to be performed before/after the all target -pre-all:: - @# Extension point - $(HIDE)if [ "$(COQMAKEFILE_VERSION)" != "$(COQ_VERSION)" ]; then\ - echo "W: This Makefile was generated by Coq $(COQMAKEFILE_VERSION)";\ - echo "W: while the current Coq version is $(COQ_VERSION)";\ - fi -.PHONY: pre-all - -post-all:: - @# Extension point -.PHONY: post-all - -real-all: $(VOFILES) $(if $(USEBYTE),bytefiles,optfiles) -.PHONY: real-all - -real-all.timing.diff: $(VOFILES:.vo=.v.timing.diff) -.PHONY: real-all.timing.diff - -bytefiles: $(CMOFILES) $(CMAFILES) -.PHONY: bytefiles - -optfiles: $(if $(DO_NATDYNLINK),$(CMXSFILES)) -.PHONY: optfiles - -# FIXME, see Ralf's bugreport -quick: $(VOFILES:.vo=.vio) -.PHONY: quick - -vio2vo: - $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) \ - -schedule-vio2vo $(J) $(VOFILES:%.vo=%.vio) -.PHONY: vio2vo - -quick2vo: - $(HIDE)make -j $(J) quick - $(HIDE)VIOFILES=$$(for vofile in $(VOFILES); do \ - viofile="$$(echo "$$vofile" | sed "s/\.vo$$/.vio/")"; \ - if [ "$$vofile" -ot "$$viofile" -o ! -e "$$vofile" ]; then printf "$$viofile "; fi; \ - done); \ - echo "VIO2VO: $$VIOFILES"; \ - if [ -n "$$VIOFILES" ]; then \ - $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) -schedule-vio2vo $(J) $$VIOFILES; \ - fi -.PHONY: quick2vo - -checkproofs: - $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) \ - -schedule-vio-checking $(J) $(VOFILES:%.vo=%.vio) -.PHONY: checkproofs - -validate: $(VOFILES) - $(TIMER) $(COQCHK) $(COQCHKFLAGS) $(COQLIBS) $^ -.PHONY: validate - -only: $(TGTS) -.PHONY: only - -# Documentation targets ####################################################### - -html: $(GLOBFILES) $(VFILES) - $(SHOW)'COQDOC -d html $(GAL)' - $(HIDE)mkdir -p html - $(HIDE)$(COQDOC) \ - -toc $(COQDOCFLAGS) -html $(GAL) $(COQDOCLIBS) -d html $(VFILES) - -mlihtml: $(MLIFILES:.mli=.cmi) - $(SHOW)'CAMLDOC -d $@' - $(HIDE)mkdir $@ || rm -rf $@/* - $(HIDE)$(CAMLDOC) -html \ - -d $@ -m A $(CAMLDEBUG) $(CAMLDOCFLAGS) $(MLIFILES) - -all-mli.tex: $(MLIFILES:.mli=.cmi) - $(SHOW)'CAMLDOC -latex $@' - $(HIDE)$(CAMLDOC) -latex \ - -o $@ -m A $(CAMLDEBUG) $(CAMLDOCFLAGS) $(MLIFILES) - -all.ps: $(VFILES) - $(SHOW)'COQDOC -ps $(GAL)' - $(HIDE)$(COQDOC) \ - -toc $(COQDOCFLAGS) -ps $(GAL) $(COQDOCLIBS) \ - -o $@ `$(COQDEP) -sort -suffix .v $(VFILES)` - -all.pdf: $(VFILES) - $(SHOW)'COQDOC -pdf $(GAL)' - $(HIDE)$(COQDOC) \ - -toc $(COQDOCFLAGS) -pdf $(GAL) $(COQDOCLIBS) \ - -o $@ `$(COQDEP) -sort -suffix .v $(VFILES)` - -# FIXME: not quite right, since the output name is different -gallinahtml: GAL=-g -gallinahtml: html - -all-gal.ps: GAL=-g -all-gal.ps: all.ps - -all-gal.pdf: GAL=-g -all-gal.pdf: all.pdf - -# ? -beautify: $(BEAUTYFILES) - for file in $^; do mv $${file%.beautified} $${file%beautified}old && mv $${file} $${file%.beautified}; done - @echo 'Do not do "make clean" until you are sure that everything went well!' - @echo 'If there were a problem, execute "for file in $$(find . -name \*.v.old -print); do mv $${file} $${file%.old}; done" in your shell/' -.PHONY: beautify - -# Installation targets ######################################################## -# -# There rules can be extended in Makefile.local -# Extensions can't assume when they run. - -install: - $(HIDE)for f in $(FILESTOINSTALL); do\ - df="`$(COQMKFILE) -destination-of "$$f" $(COQLIBS)`";\ - if [ "$$?" != "0" -o -z "$$df" ]; then\ - echo SKIP "$$f" since it has no logical path;\ - else\ - install -d "$(COQLIBINSTALL)/$$df" &&\ - install -m 0644 "$$f" "$(COQLIBINSTALL)/$$df" &&\ - echo INSTALL "$$f" "$(COQLIBINSTALL)/$$df";\ - fi;\ - done - $(HIDE)$(MAKE) install-extra -f "$(SELF)" -install-extra:: - @# Extension point -.PHONY: install install-extra - -install-byte: - $(HIDE)for f in $(BYTEFILESTOINSTALL); do\ - df="`$(COQMKFILE) -destination-of "$$f" $(COQLIBS)`";\ - if [ "$$?" != "0" -o -z "$$df" ]; then\ - echo SKIP "$$f" since it has no logical path;\ - else\ - install -d "$(COQLIBINSTALL)/$$df" &&\ - install -m 0644 "$$f" "$(COQLIBINSTALL)/$$df" &&\ - echo INSTALL "$$f" "$(COQLIBINSTALL)/$$df";\ - fi;\ - done - -install-doc:: html mlihtml - @# Extension point - $(HIDE)install -d "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/html" - $(HIDE)for i in html/*; do \ - dest="$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/$$i";\ - install -m 0644 "$$i" "$$dest";\ - echo INSTALL "$$i" "$$dest";\ - done - $(HIDE)install -d \ - "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/mlihtml" - $(HIDE)for i in mlihtml/*; do \ - dest="$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/$$i";\ - install -m 0644 "$$i" "$$dest";\ - echo INSTALL "$$i" "$$dest";\ - done -.PHONY: install-doc - -uninstall:: - @# Extension point - $(HIDE)for f in $(FILESTOINSTALL); do \ - df="`$(COQMKFILE) -destination-of "$$f" $(COQLIBS)`" &&\ - instf="$(COQLIBINSTALL)/$$df/`basename $$f`" &&\ - rm -f "$$instf" &&\ - echo RM "$$instf" &&\ - (rmdir "$(call concat_path,,$(COQLIBINSTALL)/$$df/)" 2>/dev/null || true); \ - done -.PHONY: uninstall - -uninstall-doc:: - @# Extension point - $(SHOW)'RM $(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/html' - $(HIDE)rm -rf "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/html" - $(SHOW)'RM $(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/mlihtml' - $(HIDE)rm -rf "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/mlihtml" - $(HIDE) rmdir "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/" || true -.PHONY: uninstall-doc - -# Cleaning #################################################################### -# -# There rules can be extended in Makefile.local -# Extensions can't assume when they run. - -clean:: - @# Extension point - $(SHOW)'CLEAN' - $(HIDE)rm -f $(CMOFILES) - $(HIDE)rm -f $(CMIFILES) - $(HIDE)rm -f $(CMAFILES) - $(HIDE)rm -f $(CMOFILES:.cmo=.cmx) - $(HIDE)rm -f $(CMXAFILES) - $(HIDE)rm -f $(CMXSFILES) - $(HIDE)rm -f $(CMOFILES:.cmo=.o) - $(HIDE)rm -f $(CMXAFILES:.cmxa=.a) - $(HIDE)rm -f $(ALLDFILES) - $(HIDE)rm -f $(NATIVEFILES) - $(HIDE)find . -name .coq-native -type d -empty -delete - $(HIDE)rm -f $(VOFILES) - $(HIDE)rm -f $(VOFILES:.vo=.vio) - $(HIDE)rm -f $(BEAUTYFILES) $(VFILES:=.old) - $(HIDE)rm -f all.ps all-gal.ps all.pdf all-gal.pdf all.glob all-mli.tex - $(HIDE)rm -f $(VFILES:.v=.glob) - $(HIDE)rm -f $(VFILES:.v=.tex) - $(HIDE)rm -f $(VFILES:.v=.g.tex) - $(HIDE)rm -f pretty-timed-success.ok - $(HIDE)rm -rf html mlihtml -.PHONY: clean - -cleanall:: clean - @# Extension point - $(SHOW)'CLEAN *.aux *.timing' - $(HIDE)rm -f $(foreach f,$(VFILES:.v=),$(dir $(f)).$(notdir $(f)).aux) - $(HIDE)rm -f $(TIME_OF_BUILD_FILE) $(TIME_OF_BUILD_BEFORE_FILE) $(TIME_OF_BUILD_AFTER_FILE) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BOTH_BUILD_FILE) - $(HIDE)rm -f $(VOFILES:.vo=.v.timing) - $(HIDE)rm -f $(VOFILES:.vo=.v.before-timing) - $(HIDE)rm -f $(VOFILES:.vo=.v.after-timing) - $(HIDE)rm -f $(VOFILES:.vo=.v.timing.diff) -.PHONY: cleanall - -archclean:: - @# Extension point - $(SHOW)'CLEAN *.cmx *.o' - $(HIDE)rm -f $(NATIVEFILES) - $(HIDE)rm -f $(CMOFILES:%.cmo=%.cmx) -.PHONY: archclean - - -# Compilation rules ########################################################### - -$(MLIFILES:.mli=.cmi): %.cmi: %.mli - $(SHOW)'CAMLC -c $<' - $(HIDE)$(CAMLC) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) $< - -$(ML4FILES:.ml4=.cmo): %.cmo: %.ml4 - $(SHOW)'CAMLC -pp -c $<' - $(HIDE)$(CAMLC) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) $(PP) -impl $< - -$(ML4FILES:.ml4=.cmx): %.cmx: %.ml4 - $(SHOW)'CAMLOPT -pp -c $(FOR_PACK) $<' - $(HIDE)$(CAMLOPTC) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) $(PP) $(FOR_PACK) -impl $< - -$(MLFILES:.ml=.cmo): %.cmo: %.ml - $(SHOW)'CAMLC -c $<' - $(HIDE)$(CAMLC) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) $< - -$(MLFILES:.ml=.cmx): %.cmx: %.ml - $(SHOW)'CAMLOPT -c $(FOR_PACK) $<' - $(HIDE)$(CAMLOPTC) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) $(FOR_PACK) $< - - -$(MLLIBFILES:.mllib=.cmxs): %.cmxs: %.cmxa - $(SHOW)'CAMLOPT -shared -o $@' - $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) \ - -linkall -shared -o $@ $< - -$(MLLIBFILES:.mllib=.cma): %.cma: | %.mllib - $(SHOW)'CAMLC -a -o $@' - $(HIDE)$(CAMLLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) -a -o $@ $^ - -$(MLLIBFILES:.mllib=.cmxa): %.cmxa: | %.mllib - $(SHOW)'CAMLOPT -a -o $@' - $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) -a -o $@ $^ - - -$(MLPACKFILES:.mlpack=.cmxs): %.cmxs: %.cmxa - $(SHOW)'CAMLOPT -shared -o $@' - $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) \ - -shared -linkall -o $@ $< - -$(MLPACKFILES:.mlpack=.cmxa): %.cmxa: %.cmx - $(SHOW)'CAMLOPT -a -o $@' - $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) -a -o $@ $< - -$(MLPACKFILES:.mlpack=.cma): %.cma: %.cmo | %.mlpack - $(SHOW)'CAMLC -a -o $@' - $(HIDE)$(CAMLLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) -a -o $@ $^ - -$(MLPACKFILES:.mlpack=.cmo): %.cmo: | %.mlpack - $(SHOW)'CAMLC -pack -o $@' - $(HIDE)$(CAMLLINK) $(CAMLDEBUG) $(CAMLFLAGS) -pack -o $@ $^ - -$(MLPACKFILES:.mlpack=.cmx): %.cmx: | %.mlpack - $(SHOW)'CAMLOPT -pack -o $@' - $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) -pack -o $@ $^ - -# This rule is for _CoqProject with no .mllib nor .mlpack -$(filter-out $(MLLIBFILES:.mllib=.cmxs) $(MLPACKFILES:.mlpack=.cmxs) $(addsuffix .cmxs,$(PACKEDFILES)) $(addsuffix .cmxs,$(LIBEDFILES)),$(MLFILES:.ml=.cmxs) $(ML4FILES:.ml4=.cmxs)): %.cmxs: %.cmx - $(SHOW)'[deprecated,use-mllib-or-mlpack] CAMLOPT -shared -o $@' - $(HIDE)$(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(CAMLPKGS) \ - -shared -o $@ $< - -ifneq (,$(TIMING)) -TIMING_EXTRA = > $<.$(TIMING_EXT) -else -TIMING_EXTRA = -endif - -$(VOFILES): %.vo: %.v - $(SHOW)COQC $< - $(HIDE)$(TIMER) $(COQC) $(COQDEBUG) $(TIMING_ARG) $(COQFLAGS) $(COQLIBS) $< $(TIMING_EXTRA) - -# FIXME ?merge with .vo / .vio ? -$(GLOBFILES): %.glob: %.v - $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) $< - -$(VFILES:.v=.vio): %.vio: %.v - $(SHOW)COQC -quick $< - $(HIDE)$(TIMER) $(COQC) -quick $(COQDEBUG) $(COQFLAGS) $(COQLIBS) $< - -$(addsuffix .timing.diff,$(VFILES)): %.timing.diff : %.before-timing %.after-timing - $(SHOW)PYTHON TIMING-DIFF $< - $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" print-pretty-single-time-diff BEFORE=$*.before-timing AFTER=$*.after-timing TIME_OF_PRETTY_BUILD_FILE="$@" - -$(BEAUTYFILES): %.v.beautified: %.v - $(SHOW)'BEAUTIFY $<' - $(HIDE)$(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) -beautify $< - -$(TEXFILES): %.tex: %.v - $(SHOW)'COQDOC -latex $<' - $(HIDE)$(COQDOC) $(COQDOCFLAGS) -latex $< -o $@ - -$(GTEXFILES): %.g.tex: %.v - $(SHOW)'COQDOC -latex -g $<' - $(HIDE)$(COQDOC) $(COQDOCFLAGS) -latex -g $< -o $@ - -$(HTMLFILES): %.html: %.v %.glob - $(SHOW)'COQDOC -html $<' - $(HIDE)$(COQDOC) $(COQDOCFLAGS) -html $< -o $@ - -$(GHTMLFILES): %.g.html: %.v %.glob - $(SHOW)'COQDOC -html -g $<' - $(HIDE)$(COQDOC) $(COQDOCFLAGS) -html -g $< -o $@ - -# Dependency files ############################################################ - -ifneq ($(filter-out archclean clean cleanall printenv make-pretty-timed make-pretty-timed-before make-pretty-timed-after print-pretty-timed print-pretty-timed-diff print-pretty-single-time-diff,$(MAKECMDGOALS)),) - -include $(ALLDFILES) -else - ifeq ($(MAKECMDGOALS),) - -include $(ALLDFILES) - endif -endif - -.SECONDARY: $(ALLDFILES) - -redir_if_ok = > "$@" || ( RV=$$?; rm -f "$@"; exit $$RV ) - -$(addsuffix .d,$(MLIFILES)): %.mli.d: %.mli - $(SHOW)'CAMLDEP $<' - $(HIDE)$(CAMLDEP) $(OCAMLLIBS) "$<" $(redir_if_ok) - -$(addsuffix .d,$(ML4FILES)): %.ml4.d: %.ml4 - $(SHOW)'CAMLDEP -pp $<' - $(HIDE)$(CAMLDEP) $(OCAMLLIBS) $(PP) -impl "$<" $(redir_if_ok) - -$(addsuffix .d,$(MLFILES)): %.ml.d: %.ml - $(SHOW)'CAMLDEP $<' - $(HIDE)$(CAMLDEP) $(OCAMLLIBS) "$<" $(redir_if_ok) - -$(addsuffix .d,$(MLLIBFILES)): %.mllib.d: %.mllib - $(SHOW)'COQDEP $<' - $(HIDE)$(COQDEP) $(OCAMLLIBS) -c "$<" $(redir_if_ok) - -$(addsuffix .d,$(MLPACKFILES)): %.mlpack.d: %.mlpack - $(SHOW)'COQDEP $<' - $(HIDE)$(COQDEP) $(OCAMLLIBS) -c "$<" $(redir_if_ok) - -# If this makefile is created using a _CoqProject we have coqdep get -# options from it. This avoids argument length limits for pathological -# projects. Note that extra options might be on the command line. -VDFILE_FLAGS:=$(if _CoqProject,-f _CoqProject,) $(CMDLINE_COQLIBS) $(CMDLINE_VFILES) - -$(VDFILE).d: $(VFILES) - $(SHOW)'COQDEP VFILES' - $(HIDE)$(COQDEP) -dyndep var $(VDFILE_FLAGS) $(redir_if_ok) - -# Misc ######################################################################## - -byte: - $(HIDE)$(MAKE) all "OPT:=-byte" -f "$(SELF)" -.PHONY: byte - -opt: - $(HIDE)$(MAKE) all "OPT:=-opt" -f "$(SELF)" -.PHONY: opt - -# This is deprecated. To extend this makefile use -# extension points and Makefile.local -printenv:: - $(warning printenv is deprecated) - $(warning write extensions in Makefile.local or include Makefile.conf) - @echo 'LOCAL = $(LOCAL)' - @echo 'COQLIB = $(COQLIB)' - @echo 'DOCDIR = $(DOCDIR)' - @echo 'OCAMLFIND = $(OCAMLFIND)' - @echo 'CAMLP5O = $(CAMLP5O)' - @echo 'CAMLP5BIN = $(CAMLP5BIN)' - @echo 'CAMLP5LIB = $(CAMLP5LIB)' - @echo 'CAMLP5OPTIONS = $(CAMLP5OPTIONS)' - @echo 'HASNATDYNLINK = $(HASNATDYNLINK)' - @echo 'SRC_SUBDIRS = $(SRC_SUBDIRS)' - @echo 'COQ_SRC_SUBDIRS = $(COQ_SRC_SUBDIRS)' - @echo 'OCAMLFIND = $(OCAMLFIND)' - @echo 'PP = $(PP)' - @echo 'COQFLAGS = $(COQFLAGS)' - @echo 'COQLIB = $(COQLIBS)' - @echo 'COQLIBINSTALL = $(COQLIBINSTALL)' - @echo 'COQDOCINSTALL = $(COQDOCINSTALL)' -.PHONY: printenv - -# Generate a .merlin file. If you need to append directives to this -# file you can extend the merlin-hook target in Makefile.local -.merlin: - $(SHOW)'FILL .merlin' - $(HIDE)echo 'FLG $(COQMF_CAMLFLAGS)' > .merlin - $(HIDE)echo 'B $(COQLIB)' >> .merlin - $(HIDE)echo 'S $(COQLIB)' >> .merlin - $(HIDE)$(foreach d,$(COQ_SRC_SUBDIRS), \ - echo 'B $(COQLIB)$(d)' >> .merlin;) - $(HIDE)$(foreach d,$(COQ_SRC_SUBDIRS), \ - echo 'S $(COQLIB)$(d)' >> .merlin;) - $(HIDE)$(foreach d,$(SRC_SUBDIRS), echo 'B $(d)' >> .merlin;) - $(HIDE)$(foreach d,$(SRC_SUBDIRS), echo 'S $(d)' >> .merlin;) - $(HIDE)$(MAKE) merlin-hook -f "$(SELF)" -.PHONY: merlin - -merlin-hook:: - @# Extension point -.PHONY: merlin-hook - -# prints all variables -debug: - $(foreach v,\ - $(sort $(filter-out $(INITIAL_VARS) INITIAL_VARS,\ - $(.VARIABLES))),\ - $(info $(v) = $($(v)))) -.PHONY: debug - -.DEFAULT_GOAL := all From 92d938a6f8eea84161a0db96fbf9cf78898c1b29 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Fri, 17 Sep 2021 12:19:10 -0500 Subject: [PATCH 26/39] minor tweaks --- build.sh | 1 + src/dune | 39 ++++++++++++++++++++++++++++++--------- theories/Plib.v | 1 - 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/build.sh b/build.sh index f65751b..aa9258e 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,5 @@ opam pin dune 2.7.1 +opam pin coq-serapi 8.9.0+0.6.1 dune clean dune build @all dune install diff --git a/src/dune b/src/dune index a1051ea..b399508 100644 --- a/src/dune +++ b/src/dune @@ -4,8 +4,10 @@ (synopsis "Coq Plugin Lib") (flags :standard -w -27 -warn-error -A) ; CoqPP codes requires this (modules ("plibrary")) + (library_flags -linkall) (libraries coq.vernac ; needed for vernac extend + coq.plugins.ltac ; needed only for tactic extend coq-serapi.serlib coq-plugin-lib.utilities coq-plugin-lib.coq @@ -26,19 +28,38 @@ coq-plugin-lib.termutils )) +(rule + (targets plibrary.ml) + (deps (:pp-file plibrary.ml4) ) + (action (bash "camlp5 pa_o.cmo pr_o.cmo pa_op.cmo pr_dump.cmo pa_extend.cmo q_MLast.cmo pa_macro.cmo %{lib:coq.grammar:grammar.cma} -loc loc -impl %{pp-file} -o %{targets}"))) +; camlp5 may need the following additional libs, YMMV +; pa_op.cmo pr_dump.cmo pa_extend.cmo q_MLast.cmo pa_macro.cmo + (rule (targets plib_full_plugin.cmxs) - (action (run %{ocamlopt} -shared -linkall -o %{targets}))) - + (action (run %{ocamlopt} -shared -linkall -o %{targets} + %{lib:coq.plugins.ltac:ltac_plugin.cmx} + %{lib:coq-plugin-lib.utilities:utilities.cmxa} + %{lib:coq-plugin-lib.representationutils:representationutils.cmxa} + %{lib:coq-plugin-lib.state:state.cmxa} + %{lib:coq-plugin-lib.termutils:termutils.cmxa} + %{lib:coq-plugin-lib.inference:inference.cmxa} + %{lib:coq-plugin-lib.constants:constants.cmxa} + %{lib:coq-plugin-lib.envs:envs.cmxa} + %{lib:coq-plugin-lib.typesandequality:typesandequality.cmxa} + %{lib:coq-plugin-lib.hofs:hofs.cmxa} + %{lib:coq-plugin-lib.debruijn:debruijn.cmxa} + %{lib:coq-plugin-lib.hofimpls:hofimpls.cmxa} + %{lib:coq-plugin-lib.inductive:inductive.cmxa} + %{lib:coq-plugin-lib.contexts:contexts.cmxa} + %{lib:coq-plugin-lib.transformation:transformation.cmxa} + %{lib:coq-plugin-lib.devutils:devutils.cmxa} + %{lib:coq-plugin-lib.decompiler:decompiler.cmxa} + %{lib:coq-plugin-lib.coq:coq.cmxa} + %{cmxa:plib}))) + (install (section lib_root) (package coq-plugin-lib) (files (plib_full_plugin.cmxs as coq/user-contrib/plib_full_plugin.cmxs))) - -(rule - (targets plibrary.ml) - (deps (:pp-file plibrary.ml4) ) - (action (bash "camlp5 pa_o.cmo pr_o.cmo %{lib:coq.grammar:grammar.cma} -loc loc -impl %{pp-file} -o %{targets}"))) -; camlp5 may need the following additional libs, YMMV -; pa_op.cmo pr_dump.cmo pa_extend.cmo q_MLast.cmo pa_macro.cmo diff --git a/theories/Plib.v b/theories/Plib.v index 9ead491..4382fcb 100644 --- a/theories/Plib.v +++ b/theories/Plib.v @@ -1,3 +1,2 @@ (* Uses the ad-hoc .cmxs file *) Declare ML Module "plib_full_plugin". - From aa945684bca872dcebc9a64c28037433023d561e Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 21 Sep 2021 17:21:21 -0500 Subject: [PATCH 27/39] use Lymp instead, get building --- README.md | 2 + build.sh | 2 + src/coq/constants/.merlin | 32 --------- src/coq/decompiler/.merlin | 72 --------------------- src/coq/devutils/.merlin | 70 -------------------- src/coq/logicutils/contexts/.merlin | 68 ------------------- src/coq/logicutils/contexts/envs/.merlin | 52 --------------- src/coq/logicutils/contexts/state/.merlin | 30 --------- src/coq/logicutils/debruijn/.merlin | 58 ----------------- src/coq/logicutils/hofs/.merlin | 56 ---------------- src/coq/logicutils/hofs/impls/.merlin | 64 ------------------ src/coq/logicutils/inductive/.merlin | 66 ------------------- src/coq/logicutils/inference/.merlin | 26 -------- src/coq/logicutils/transformation/.merlin | 70 -------------------- src/coq/logicutils/typesandequality/.merlin | 54 ---------------- src/coq/representationutils/.merlin | 40 ------------ src/coq/termutils/.merlin | 26 -------- src/dune | 6 ++ src/plibrary.ml4 | 5 +- theories/dune | 2 +- 20 files changed, 14 insertions(+), 787 deletions(-) delete mode 100644 src/coq/constants/.merlin delete mode 100644 src/coq/decompiler/.merlin delete mode 100644 src/coq/devutils/.merlin delete mode 100644 src/coq/logicutils/contexts/.merlin delete mode 100644 src/coq/logicutils/contexts/envs/.merlin delete mode 100644 src/coq/logicutils/contexts/state/.merlin delete mode 100644 src/coq/logicutils/debruijn/.merlin delete mode 100644 src/coq/logicutils/hofs/.merlin delete mode 100644 src/coq/logicutils/hofs/impls/.merlin delete mode 100644 src/coq/logicutils/inductive/.merlin delete mode 100644 src/coq/logicutils/inference/.merlin delete mode 100644 src/coq/logicutils/transformation/.merlin delete mode 100644 src/coq/logicutils/typesandequality/.merlin delete mode 100644 src/coq/representationutils/.merlin delete mode 100644 src/coq/termutils/.merlin diff --git a/README.md b/README.md index ebb8db3..0a59dac 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ See [PUMPKIN PATCH](https://github.com/uwplse/PUMPKIN-PATCH) and [DEVOID](https: ## Guide +This code guide is out of date and needs to be updated due to the switch to use Dune. + * [LICENSE](/LICENSE): License * [README.md](/README.md): You are here! * [build.sh](/build.sh): Build script for example plugin diff --git a/build.sh b/build.sh index aa9258e..d280d59 100755 --- a/build.sh +++ b/build.sh @@ -1,5 +1,7 @@ opam pin dune 2.7.1 opam pin coq-serapi 8.9.0+0.6.1 +opam install lymp dune clean dune build @all +dune build @all dune install diff --git a/src/coq/constants/.merlin b/src/coq/constants/.merlin deleted file mode 100644 index e3b8305..0000000 --- a/src/coq/constants/.merlin +++ /dev/null @@ -1,32 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../_build/default/src/coq/constants/.constants.objs/byte -B ../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../_build/default/src/coq/termutils/.termutils.objs/byte -B ../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S . -S ../logicutils/inference -S ../termutils -S ../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/decompiler/.merlin b/src/coq/decompiler/.merlin deleted file mode 100644 index 9108183..0000000 --- a/src/coq/decompiler/.merlin +++ /dev/null @@ -1,72 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/stm -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../_build/default/src/coq/constants/.constants.objs/byte -B ../../../_build/default/src/coq/decompiler/.decompiler.objs/byte -B ../../../_build/default/src/coq/devutils/.devutils.objs/byte -B ../../../_build/default/src/coq/logicutils/contexts/.contexts.objs/byte -B ../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte -B ../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte -B ../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte -B ../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte -B ../../../_build/default/src/coq/logicutils/inductive/.inductive.objs/byte -B ../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte -B ../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -B ../../../_build/default/src/coq/termutils/.termutils.objs/byte -B ../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/stm -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S ../constants -S . -S ../devutils -S ../logicutils/contexts -S ../logicutils/contexts/envs -S ../logicutils/contexts/state -S ../logicutils/debruijn -S ../logicutils/hofs -S ../logicutils/hofs/impls -S ../logicutils/inductive -S ../logicutils/inference -S ../logicutils/typesandequality -S ../representationutils -S ../termutils -S ../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/devutils/.merlin b/src/coq/devutils/.merlin deleted file mode 100644 index 5afe5d8..0000000 --- a/src/coq/devutils/.merlin +++ /dev/null @@ -1,70 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/stm -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../_build/default/src/coq/constants/.constants.objs/byte -B ../../../_build/default/src/coq/devutils/.devutils.objs/byte -B ../../../_build/default/src/coq/logicutils/contexts/.contexts.objs/byte -B ../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte -B ../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte -B ../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte -B ../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte -B ../../../_build/default/src/coq/logicutils/inductive/.inductive.objs/byte -B ../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte -B ../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -B ../../../_build/default/src/coq/termutils/.termutils.objs/byte -B ../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/stm -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S ../constants -S . -S ../logicutils/contexts -S ../logicutils/contexts/envs -S ../logicutils/contexts/state -S ../logicutils/debruijn -S ../logicutils/hofs -S ../logicutils/hofs/impls -S ../logicutils/inductive -S ../logicutils/inference -S ../logicutils/typesandequality -S ../representationutils -S ../termutils -S ../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/contexts/.merlin b/src/coq/logicutils/contexts/.merlin deleted file mode 100644 index 852cd1f..0000000 --- a/src/coq/logicutils/contexts/.merlin +++ /dev/null @@ -1,68 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/stm -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../../_build/default/src/coq/constants/.constants.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/.contexts.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte -B ../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte -B ../../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte -B ../../../../_build/default/src/coq/logicutils/inductive/.inductive.objs/byte -B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte -B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -B ../../../../_build/default/src/coq/termutils/.termutils.objs/byte -B ../../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/stm -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S ../../constants -S . -S envs -S state -S ../debruijn -S ../hofs -S ../hofs/impls -S ../inductive -S ../inference -S ../typesandequality -S ../../representationutils -S ../../termutils -S ../../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/contexts/envs/.merlin b/src/coq/logicutils/contexts/envs/.merlin deleted file mode 100644 index 4959868..0000000 --- a/src/coq/logicutils/contexts/envs/.merlin +++ /dev/null @@ -1,52 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/stm -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte -B ../../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -B ../../../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/stm -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S . -S ../state -S ../../inference -S ../../../representationutils -S ../../../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/contexts/state/.merlin b/src/coq/logicutils/contexts/state/.merlin deleted file mode 100644 index 8226e53..0000000 --- a/src/coq/logicutils/contexts/state/.merlin +++ /dev/null @@ -1,30 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S . -S ../../../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/debruijn/.merlin b/src/coq/logicutils/debruijn/.merlin deleted file mode 100644 index 367f697..0000000 --- a/src/coq/logicutils/debruijn/.merlin +++ /dev/null @@ -1,58 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/stm -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte -B ../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte -B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte -B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -B ../../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/stm -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S ../contexts/envs -S ../contexts/state -S . -S ../hofs -S ../inference -S ../typesandequality -S ../../representationutils -S ../../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/hofs/.merlin b/src/coq/logicutils/hofs/.merlin deleted file mode 100644 index 756dee0..0000000 --- a/src/coq/logicutils/hofs/.merlin +++ /dev/null @@ -1,56 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/stm -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte -B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte -B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -B ../../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/stm -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S ../contexts/envs -S ../contexts/state -S . -S ../inference -S ../typesandequality -S ../../representationutils -S ../../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/hofs/impls/.merlin b/src/coq/logicutils/hofs/impls/.merlin deleted file mode 100644 index 8f31b42..0000000 --- a/src/coq/logicutils/hofs/impls/.merlin +++ /dev/null @@ -1,64 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/stm -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../../../_build/default/src/coq/constants/.constants.objs/byte -B ../../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte -B ../../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte -B ../../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte -B ../../../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte -B ../../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte -B ../../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -B ../../../../../_build/default/src/coq/termutils/.termutils.objs/byte -B ../../../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/stm -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S ../../../constants -S ../../contexts/envs -S ../../contexts/state -S ../../debruijn -S .. -S . -S ../../inference -S ../../typesandequality -S ../../../representationutils -S ../../../termutils -S ../../../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/inductive/.merlin b/src/coq/logicutils/inductive/.merlin deleted file mode 100644 index 38a0139..0000000 --- a/src/coq/logicutils/inductive/.merlin +++ /dev/null @@ -1,66 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/stm -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../../_build/default/src/coq/constants/.constants.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte -B ../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte -B ../../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte -B ../../../../_build/default/src/coq/logicutils/inductive/.inductive.objs/byte -B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte -B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -B ../../../../_build/default/src/coq/termutils/.termutils.objs/byte -B ../../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/stm -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S ../../constants -S ../contexts/envs -S ../contexts/state -S ../debruijn -S ../hofs -S ../hofs/impls -S . -S ../inference -S ../typesandequality -S ../../representationutils -S ../../termutils -S ../../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/inference/.merlin b/src/coq/logicutils/inference/.merlin deleted file mode 100644 index b0fe410..0000000 --- a/src/coq/logicutils/inference/.merlin +++ /dev/null @@ -1,26 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S . -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/transformation/.merlin b/src/coq/logicutils/transformation/.merlin deleted file mode 100644 index 21e2be6..0000000 --- a/src/coq/logicutils/transformation/.merlin +++ /dev/null @@ -1,70 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/stm -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../../_build/default/src/coq/constants/.constants.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/.contexts.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../../_build/default/src/coq/logicutils/debruijn/.debruijn.objs/byte -B ../../../../_build/default/src/coq/logicutils/hofs/.hofs.objs/byte -B ../../../../_build/default/src/coq/logicutils/hofs/impls/.hofimpls.objs/byte -B ../../../../_build/default/src/coq/logicutils/inductive/.inductive.objs/byte -B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../../_build/default/src/coq/logicutils/transformation/.transformation.objs/byte -B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte -B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -B ../../../../_build/default/src/coq/termutils/.termutils.objs/byte -B ../../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/stm -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S ../../constants -S ../contexts -S ../contexts/envs -S ../contexts/state -S ../debruijn -S ../hofs -S ../hofs/impls -S ../inductive -S ../inference -S . -S ../typesandequality -S ../../representationutils -S ../../termutils -S ../../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/logicutils/typesandequality/.merlin b/src/coq/logicutils/typesandequality/.merlin deleted file mode 100644 index 066802f..0000000 --- a/src/coq/logicutils/typesandequality/.merlin +++ /dev/null @@ -1,54 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/stm -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../../_build/default/src/coq/logicutils/contexts/envs/.envs.objs/byte -B ../../../../_build/default/src/coq/logicutils/contexts/state/.state.objs/byte -B ../../../../_build/default/src/coq/logicutils/inference/.inference.objs/byte -B ../../../../_build/default/src/coq/logicutils/typesandequality/.typesandequality.objs/byte -B ../../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -B ../../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/plugins/ltac -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/stm -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S ../contexts/envs -S ../contexts/state -S ../inference -S . -S ../../representationutils -S ../../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/representationutils/.merlin b/src/coq/representationutils/.merlin deleted file mode 100644 index e5a7c02..0000000 --- a/src/coq/representationutils/.merlin +++ /dev/null @@ -1,40 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/camlp5 -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/interp -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -B /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -B /home/talia/.opam/4.07.1+flambda/lib/coq/printing -B /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -B /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -B /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../_build/default/src/coq/representationutils/.representationutils.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/camlp5 -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/interp -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/coq/parsing -S /home/talia/.opam/4.07.1+flambda/lib/coq/pretyping -S /home/talia/.opam/4.07.1+flambda/lib/coq/printing -S /home/talia/.opam/4.07.1+flambda/lib/coq/proofs -S /home/talia/.opam/4.07.1+flambda/lib/coq/tactics -S /home/talia/.opam/4.07.1+flambda/lib/coq/vernac -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S . -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/coq/termutils/.merlin b/src/coq/termutils/.merlin deleted file mode 100644 index 47fd2c8..0000000 --- a/src/coq/termutils/.merlin +++ /dev/null @@ -1,26 +0,0 @@ -EXCLUDE_QUERY_DIR -B /home/talia/.opam/4.07.1+flambda/lib/coq/clib -B /home/talia/.opam/4.07.1+flambda/lib/coq/config -B /home/talia/.opam/4.07.1+flambda/lib/coq/engine -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -B /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -B /home/talia/.opam/4.07.1+flambda/lib/coq/lib -B /home/talia/.opam/4.07.1+flambda/lib/coq/library -B /home/talia/.opam/4.07.1+flambda/lib/num -B /home/talia/.opam/4.07.1+flambda/lib/ocaml -B /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -B ../../../_build/default/src/coq/termutils/.termutils.objs/byte -B ../../../_build/default/src/utilities/.utilities.objs/byte -S /home/talia/.opam/4.07.1+flambda/lib/coq/clib -S /home/talia/.opam/4.07.1+flambda/lib/coq/config -S /home/talia/.opam/4.07.1+flambda/lib/coq/engine -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel -S /home/talia/.opam/4.07.1+flambda/lib/coq/kernel/byterun -S /home/talia/.opam/4.07.1+flambda/lib/coq/lib -S /home/talia/.opam/4.07.1+flambda/lib/coq/library -S /home/talia/.opam/4.07.1+flambda/lib/num -S /home/talia/.opam/4.07.1+flambda/lib/ocaml -S /home/talia/.opam/4.07.1+flambda/lib/ocaml/threads -S . -S ../../utilities -FLG -w @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -8-33-3-27-28-32 diff --git a/src/dune b/src/dune index b399508..9bec8cd 100644 --- a/src/dune +++ b/src/dune @@ -4,6 +4,7 @@ (synopsis "Coq Plugin Lib") (flags :standard -w -27 -warn-error -A) ; CoqPP codes requires this (modules ("plibrary")) + (modes native) (library_flags -linkall) (libraries coq.vernac ; needed for vernac extend @@ -26,6 +27,7 @@ coq-plugin-lib.inductive coq-plugin-lib.representationutils coq-plugin-lib.termutils + lymp )) (rule @@ -56,7 +58,11 @@ %{lib:coq-plugin-lib.devutils:devutils.cmxa} %{lib:coq-plugin-lib.decompiler:decompiler.cmxa} %{lib:coq-plugin-lib.coq:coq.cmxa} + %{lib:lymp:lymp.cmxa} %{cmxa:plib}))) + + + (install (section lib_root) diff --git a/src/plibrary.ml4 b/src/plibrary.ml4 index ed3c359..000aea1 100644 --- a/src/plibrary.ml4 +++ b/src/plibrary.ml4 @@ -26,10 +26,11 @@ open Class_tactics open Stdarg open Tacarg -open Ser_names - open List +open Ser_names +open Lymp + (* --- Commands --- *) (* Decompiles a single term into a tactic list printed to console. *) diff --git a/theories/dune b/theories/dune index e32b588..2f08575 100644 --- a/theories/dune +++ b/theories/dune @@ -1,5 +1,5 @@ (coq.theory (name CoqPluginLib) (package coq-plugin-lib) - (flags -q -noinit -I ./src) + (flags -q -I ./src) ) From a5bdacbc2cbc7201b770afddbea560e0dca5b4b1 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 21 Sep 2021 17:21:31 -0500 Subject: [PATCH 28/39] ignore .merlin files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bc89608..81c72b9 100644 --- a/.gitignore +++ b/.gitignore @@ -21,5 +21,6 @@ plugin/Makefile.coq plugin/Makefile.conf plugin/Makefile plugin/.merlin +*.merlin *.out _opam From b31af2273be588ab6c06e9c2a73eebb7287633cb Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 21 Sep 2021 17:27:39 -0500 Subject: [PATCH 29/39] don't restrict mode --- src/dune | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dune b/src/dune index 9bec8cd..e41a58c 100644 --- a/src/dune +++ b/src/dune @@ -4,7 +4,6 @@ (synopsis "Coq Plugin Lib") (flags :standard -w -27 -warn-error -A) ; CoqPP codes requires this (modules ("plibrary")) - (modes native) (library_flags -linkall) (libraries coq.vernac ; needed for vernac extend From c067347232699aaa177a9f0a149d2a92fd080199 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 21 Sep 2021 17:42:16 -0500 Subject: [PATCH 30/39] Why did that one work? --- src/dune | 9 ++------- src/plibrary.ml4 | 1 - theories/dune | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/dune b/src/dune index e41a58c..7742c4d 100644 --- a/src/dune +++ b/src/dune @@ -32,13 +32,12 @@ (rule (targets plibrary.ml) (deps (:pp-file plibrary.ml4) ) - (action (bash "camlp5 pa_o.cmo pr_o.cmo pa_op.cmo pr_dump.cmo pa_extend.cmo q_MLast.cmo pa_macro.cmo %{lib:coq.grammar:grammar.cma} -loc loc -impl %{pp-file} -o %{targets}"))) -; camlp5 may need the following additional libs, YMMV -; pa_op.cmo pr_dump.cmo pa_extend.cmo q_MLast.cmo pa_macro.cmo + (action (bash "camlp5 pa_o.cmo pr_o.cmo pa_op.cmo pr_dump.cmo pa_extend.cmo q_MLast.cmo pa_macro.cmo pa_op.cmo pr_dump.cmo pa_extend.cmo q_MLast.cmo pa_macro.cmo %{lib:coq.grammar:grammar.cma} -loc loc -impl %{pp-file} -o %{targets}"))) (rule (targets plib_full_plugin.cmxs) (action (run %{ocamlopt} -shared -linkall -o %{targets} + %{lib:lymp:lymp.cmxa} %{lib:coq.plugins.ltac:ltac_plugin.cmx} %{lib:coq-plugin-lib.utilities:utilities.cmxa} %{lib:coq-plugin-lib.representationutils:representationutils.cmxa} @@ -57,11 +56,7 @@ %{lib:coq-plugin-lib.devutils:devutils.cmxa} %{lib:coq-plugin-lib.decompiler:decompiler.cmxa} %{lib:coq-plugin-lib.coq:coq.cmxa} - %{lib:lymp:lymp.cmxa} %{cmxa:plib}))) - - - (install (section lib_root) diff --git a/src/plibrary.ml4 b/src/plibrary.ml4 index 000aea1..4254523 100644 --- a/src/plibrary.ml4 +++ b/src/plibrary.ml4 @@ -1,4 +1,3 @@ - DECLARE PLUGIN "plib" open Decompiler diff --git a/theories/dune b/theories/dune index 2f08575..e32b588 100644 --- a/theories/dune +++ b/theories/dune @@ -1,5 +1,5 @@ (coq.theory (name CoqPluginLib) (package coq-plugin-lib) - (flags -q -I ./src) + (flags -q -noinit -I ./src) ) From 20dbd0d5a96767feafb5a827a60a2b5a2dd067dd Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 21 Sep 2021 17:49:49 -0500 Subject: [PATCH 31/39] Right, so this file is broken with some weird error loading the plugin --- coq/Test.v | 1 + 1 file changed, 1 insertion(+) create mode 100644 coq/Test.v diff --git a/coq/Test.v b/coq/Test.v new file mode 100644 index 0000000..7d158d9 --- /dev/null +++ b/coq/Test.v @@ -0,0 +1 @@ +Require Import CoqPluginLib.Plib. From a693ee3499ea96f8906a0659891d7b6d8745f2a9 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 21 Sep 2021 18:12:46 -0500 Subject: [PATCH 32/39] Remove duplicate coq.plugins.ltac --- src/dune | 3 +-- theories/dune | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/dune b/src/dune index 7742c4d..efd6d4b 100644 --- a/src/dune +++ b/src/dune @@ -4,10 +4,10 @@ (synopsis "Coq Plugin Lib") (flags :standard -w -27 -warn-error -A) ; CoqPP codes requires this (modules ("plibrary")) + (modes native) (library_flags -linkall) (libraries coq.vernac ; needed for vernac extend - coq.plugins.ltac ; needed only for tactic extend coq-serapi.serlib coq-plugin-lib.utilities coq-plugin-lib.coq @@ -38,7 +38,6 @@ (targets plib_full_plugin.cmxs) (action (run %{ocamlopt} -shared -linkall -o %{targets} %{lib:lymp:lymp.cmxa} - %{lib:coq.plugins.ltac:ltac_plugin.cmx} %{lib:coq-plugin-lib.utilities:utilities.cmxa} %{lib:coq-plugin-lib.representationutils:representationutils.cmxa} %{lib:coq-plugin-lib.state:state.cmxa} diff --git a/theories/dune b/theories/dune index e32b588..2f08575 100644 --- a/theories/dune +++ b/theories/dune @@ -1,5 +1,5 @@ (coq.theory (name CoqPluginLib) (package coq-plugin-lib) - (flags -q -noinit -I ./src) + (flags -q -I ./src) ) From 2cc029abe8a74c3165f97a53993e36e535dc8e86 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 21 Sep 2021 18:18:50 -0500 Subject: [PATCH 33/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a59dac..a8fe938 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This code guide is out of date and needs to be updated due to the switch to use ## Contributors -This library was developed by Talia Ringer, Nate Yazdani, and RanDair Porter. +This library was developed by Talia Ringer, Nate Yazdani, RanDair Porter, and Emily First. ## Licensing From 0c6ecc44ed665ce991a7ca2674724130b6badfab Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 21 Sep 2021 18:19:14 -0500 Subject: [PATCH 34/39] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index cbee369..3fa32cf 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2019 Talia Ringer, Nate Yazdani +Copyright (c) 2021 PUMPKIN PATCH Team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 4e907d5cf441f16db501bfcfebb32d2ebff186e4 Mon Sep 17 00:00:00 2001 From: Talia Ringer Date: Tue, 21 Sep 2021 18:48:12 -0500 Subject: [PATCH 35/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a8fe938..36fa2d6 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This code guide is out of date and needs to be updated due to the switch to use ## Contributors -This library was developed by Talia Ringer, Nate Yazdani, RanDair Porter, and Emily First. +This library was developed by Talia Ringer, Nate Yazdani, RanDair Porter, and Emily First. Probably none of it would build without Emilio's help. ## Licensing From 281ba24054faf18a5f758fa877ce2e0bf9fa285d Mon Sep 17 00:00:00 2001 From: efirst Date: Tue, 5 Oct 2021 13:46:24 -0400 Subject: [PATCH 36/39] integration. need to add model, sexpcache, and check whether all other files correctly added --- .gitmodules | 3 + coq/FundamentalArithmetics.v | 16 + deps/.DS_Store | Bin 0 -> 6148 bytes src/coq/tactok/.DS_Store | Bin 0 -> 6148 bytes src/coq/tactok/agent_utils.py | 67 ++++ src/coq/tactok/gallina.py | 104 ++++++ src/coq/tactok/models/embedding_map.py | 17 + src/coq/tactok/models/prover.py | 118 +++++++ src/coq/tactok/models/tactic_decoder.py | 438 ++++++++++++++++++++++++ src/coq/tactok/models/term_encoder.py | 187 ++++++++++ src/coq/tactok/options.ml | 15 + src/coq/tactok/options.mli | 10 + src/coq/tactok/tac_grammar.py | 290 ++++++++++++++++ src/coq/tactok/tactics.ebnf | 135 ++++++++ src/coq/tactok/tactok.ml | 43 +++ src/coq/tactok/tactok.mli | 20 ++ src/coq/tactok/token_vocab.pickle | Bin 0 -> 361154 bytes 17 files changed, 1463 insertions(+) create mode 100644 coq/FundamentalArithmetics.v create mode 100644 deps/.DS_Store create mode 100644 src/coq/tactok/.DS_Store create mode 100644 src/coq/tactok/agent_utils.py create mode 100644 src/coq/tactok/gallina.py create mode 100644 src/coq/tactok/models/embedding_map.py create mode 100644 src/coq/tactok/models/prover.py create mode 100644 src/coq/tactok/models/tactic_decoder.py create mode 100644 src/coq/tactok/models/term_encoder.py create mode 100644 src/coq/tactok/options.ml create mode 100644 src/coq/tactok/options.mli create mode 100644 src/coq/tactok/tac_grammar.py create mode 100644 src/coq/tactok/tactics.ebnf create mode 100644 src/coq/tactok/tactok.ml create mode 100644 src/coq/tactok/tactok.mli create mode 100644 src/coq/tactok/token_vocab.pickle diff --git a/.gitmodules b/.gitmodules index e69de29..e85e297 100644 --- a/.gitmodules +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "plugin/deps/fundamental-arithmetics"] + path = deps/fundamental-arithmetics + url = https://github.com/coq-contribs/fundamental-arithmetics diff --git a/coq/FundamentalArithmetics.v b/coq/FundamentalArithmetics.v new file mode 100644 index 0000000..a3a30c3 --- /dev/null +++ b/coq/FundamentalArithmetics.v @@ -0,0 +1,16 @@ +Add LoadPath "./deps/fundamental-arithmetics" as FundamentalArithmetics. +From FundamentalArithmetics Require Import + division euclide gcd missing nthroot permutation + power primes. +Require Import Patcher.Patch. + + +Decompile Module division. +Decompile Module euclide. +Decompile Module gcd. +Decompile Module missing. +Decompile Module nthroot. +Decompile Module permutation. +Decompile Module power. +Decompile Module primes. + diff --git a/deps/.DS_Store b/deps/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ba939f3e7113151372ce365d2182e9efbd34bc3b GIT binary patch literal 6148 zcmeHK!A{#i5S)(pxGyNL9oE$qMw)8~w2v=A+he~|&+yAFM&33e^PuKnJ>j6UFfOeuDAWc(HE3o7Gjc@<|xjLf_E zDoe}C_wQ9>rMbHH#%tku>z#(9Vj5OaH7N(t_=MjMqG}X7`>-goCp(Id(&6;1y}4K9 zRg~t#u}MyoAws?!r+HFL2gM{$N;6JqJ9wVfS$k_X>wWC^yL#LA=UqMP_x-Nk+3wBf zEwA&wxBL10^5*;O$Nc9nOTNPI)X0XzN4SOYLLQRxB8#yS9^!?m*WozNiu@ZgA3umk z5fKK20byWC47j7mTVK+AGL0}G4E#R~@cE#jjDf@2qB%Oym=XZkgxd>|d4}I}9Aw z7SRJyHWg@7l`AonO^08*xWHj;(WaAf#fNe;D_5Z?GdsrDCY)4YQCeX@82FO`uKgfw zzW+b{z5X{r(g*{>!0Ti{HTT2)0oLa3)`eB_U8|wzP!^7>Ek32dFjp~R`6_+~H3Gk8 W0~k20Ey4qlKLUmZX@r5LGVlOCNo#We literal 0 HcmV?d00001 diff --git a/src/coq/tactok/.DS_Store b/src/coq/tactok/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..86ee6639d0af80e6263bb55fe3f11bd0e70c2418 GIT binary patch literal 6148 zcmeHK!A`&{SEyizrf#d zW_KYW=*<{IW|EmV%+73?SF+16#&~NS)EO%?#sny0t_bEE!FALX$=OIAkn24nmiUuo z=ts(5$)>=6WB}jYCL1ut0@h>8@9)DOMq!fHYM(rpFKldX2~iTIozk7#R}(k&(s9!A zMmPBB!b|(U^)Ho*7QW|Sg}q6qymzYN)C=R@NEe4e4^nQg!#GfrmKw)FqW5vlf)GVf z?363h>0zT@mG#=utSYC?X00lZn~mA5DE1HPC+FS4)ARIY_WEX+oG0pjz`=9>@_1H=F^us#gf6HaWePfOGZF+dFb5(9WXNKiz_ zVrEbu9bohb09b&q7VvSFz#3`Mv6vZz6%cMp0Zl2lBL+9+5SKR3v6vY&<&4|mgWD%_ zJE3s>bl6|&bjBTnWQhS{V3`4&{Xoii|DXLl|LY_&!~ij{o(%9p+ika?H+#3PbcuJZ t1nq*NU|wc$Q38&>iXj)T;tHr1h)Z+;9gCSkh=9-^0ZjuLV&G31_yT;;SWf@| literal 0 HcmV?d00001 diff --git a/src/coq/tactok/agent_utils.py b/src/coq/tactok/agent_utils.py new file mode 100644 index 0000000..a1d4275 --- /dev/null +++ b/src/coq/tactok/agent_utils.py @@ -0,0 +1,67 @@ +import torch +import argparse +from gallina import GallinaTermParser +from models.prover import Prover +import string + +term_parser = GallinaTermParser(caching=True) +sexp_cache = SexpCache('../sexp_cache', readonly=True) #include this + +def get_opts(): + parser = argparse.ArgumentParser() + parser.add_argument('--path', type=str, default='model.pth') + parser.add_argument('--beam_width', type=int, default=10) + parser.add_argument('--tac_grammar', type=str, default='tactics.ebnf') + parser.add_argument('--term_embedding_dim', type=int, default=256) + parser.add_argument('--embedding_dim', type=int, default=256, help='dimension of the grammar embeddings') + parser.add_argument('--symbol_dim', type=int, default=256, help='dimension of the terminal/nonterminal symbol embeddings') + parser.add_argument('--hidden_dim', type=int, default=256, help='dimension of the LSTM controller') + parser.add_argument('--seed', type=int, default=0) + parser.add_argument('--num_tactics', type=int, default=15025) + parser.add_argument('--tac_vocab_file', type=str, default='token_vocab.pickle') + parser.add_argument('--cutoff_len', type=int, default=30) + opts = parser.parse_args() + opts.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + return opts + +def import_model(): + opts = get_opts() + model = Prover(opts) + if opts.device.type == 'cpu': + checkpoint = torch.load(opts.path, map_location='cpu') + else: + checkpoint = torch.load(opts.path) + model.load_state_dict(checkpoint['state_dict']) + model.to(opts.device) + return model + +def filter_env(env): + filtered_env = [] + for const in [const for const in env['constants'] if const['qualid'].startswith('SerTop')][-10:]: + ast = sexp_cache[const['sexp']] + filtered_env.append({'qualid': const['qualid'], 'ast': term_parser.parse(ast)}) + return filtered_env + +def parse_goal(g): + goal = {'id': g['id'], 'text': g['type'], 'ast': term_parser.parse(g['sexp'])} + local_context = [] + for i, h in enumerate(g['hypotheses']): + for ident in h['idents']: + local_context.append({'ident': ident, 'text': h['type'], 'ast': term_parser.parse(h['sexp'])}) + return local_context, goal['ast'] + +rem_punc = string.punctuation.replace('\'','').replace('_', '') +table = str.maketrans('', '', rem_punc) + +def tokenize_text(raw_text): + without_punc = raw_text.translate(table) + words = without_punc.split() + return words + +def parse_script(script): + prev_seq = [] + for tac in script: + tac_words = tokenize_text(tac) + prev_seq += tac_words + + return prev_seq \ No newline at end of file diff --git a/src/coq/tactok/gallina.py b/src/coq/tactok/gallina.py new file mode 100644 index 0000000..9acc5e6 --- /dev/null +++ b/src/coq/tactok/gallina.py @@ -0,0 +1,104 @@ +# Utilities for reconstructing Gallina terms from their serialized S-expressions in CoqGym +from io import StringIO +from vernac_types import Constr__constr +from lark import Lark, Transformer, Visitor, Discard +from lark.lexer import Token +from lark.tree import Tree +from lark.tree import pydot__tree_to_png +import logging +logging.basicConfig(level=logging.DEBUG) +from collections import defaultdict +import re +import pdb + + +def traverse_postorder(node, callback): + for c in node.children: + if isinstance(c, Tree): + traverse_postorder(c, callback) + callback(node) + + +class GallinaTermParser: + + def __init__(self, caching=True): + self.caching = caching + t = Constr__constr() + self.grammar = t.to_ebnf(recursive=True) + ''' + %import common.STRING_INNER + %import common.ESCAPED_STRING + %import common.SIGNED_INT + %import common.WS + %ignore WS + ''' + self.parser = Lark(StringIO(self.grammar), start='constr__constr', parser='lalr') + if caching: + self.cache = {} + + + def parse_no_cache(self, term_str): + ast = self.parser.parse(term_str) + + ast.quantified_idents = set() + + def get_quantified_idents(node): + if node.data == 'constructor_prod' and node.children != [] and node.children[0].data == 'constructor_name': + ident = node.children[0].children[0].value + if ident.startswith('"') and ident.endswith('"'): + ident = ident[1:-1] + ast.quantified_idents.add(ident) + + traverse_postorder(ast, get_quantified_idents) + ast.quantified_idents = list(ast.quantified_idents) + + def compute_height_remove_toekn(node): + children = [] + node.height = 0 + for c in node.children: + if isinstance(c, Tree): + node.height = max(node.height, c.height + 1) + children.append(c) + node.children = children + + traverse_postorder(ast, compute_height_remove_toekn) + return ast + + + def parse(self, term_str): + if self.caching: + if term_str not in self.cache: + self.cache[term_str] = self.parse_no_cache(term_str) + return self.cache[term_str] + else: + return self.parse_no_cache(term_str) + + + def print_grammar(self): + print(self.grammar) + + +class Counter(Visitor): + + def __init__(self): + super().__init__() + self.counts_nonterminal = defaultdict(int) + self.counts_terminal = defaultdict(int) + + def __default__(self, tree): + self.counts_nonterminal[tree.data] += 1 + for c in tree.children: + if isinstance(c, Token): + self.counts_terminal[c.value] += 1 + + +class TreeHeight(Transformer): + + def __default__(self, symbol, children, meta): + return 1 + max([0 if isinstance(c, Token) else c for c in children] + [-1]) + + +class TreeNumTokens(Transformer): + + def __default__(self, symbol, children, meta): + return sum([1 if isinstance(c, Token) else c for c in children]) + diff --git a/src/coq/tactok/models/embedding_map.py b/src/coq/tactok/models/embedding_map.py new file mode 100644 index 0000000..ac3db72 --- /dev/null +++ b/src/coq/tactok/models/embedding_map.py @@ -0,0 +1,17 @@ +import torch +import torch.nn as nn + +class EmbeddingMap(nn.Module): + + def __init__(self, dim, opts): + self.dim = dim + self.opts = opts + self.mapping = {} + + def __getitem__(self, key): + if key not in self.mapping: + embedding = nn.Parameters(torch.Tensor(self.dim).to(self.opts.device)) + nn.init.normal_(embedding, std=0.1) + self.mapping[key] = embedding + self.register_parameter(key, embedding) + return self.mapping[key] diff --git a/src/coq/tactok/models/prover.py b/src/coq/tactok/models/prover.py new file mode 100644 index 0000000..e53e0af --- /dev/null +++ b/src/coq/tactok/models/prover.py @@ -0,0 +1,118 @@ +import torch +import torch.nn as nn +from tac_grammar import CFG +from .tactic_decoder import TacticDecoder +from .term_encoder import TermEncoder +import pdb +import os +from itertools import chain +import sys +sys.path.append(os.path.abspath('.')) +from time import time +from torch.nn import Embedding, LSTM +import pickle + +class Prover(nn.Module): + + def __init__(self, opts): + super().__init__() + self.opts = opts + self.tactic_decoder = TacticDecoder(CFG(opts.tac_grammar, 'tactic_expr'), opts) + self.term_encoder = TermEncoder(opts) + self.tactic_embedding = Embedding(opts.num_tactics, 256, padding_idx=0) + self.tactic_LSTM = LSTM(256, 256, 1, batch_first=True, bidirectional=True) + self.tac_vocab = pickle.load(open(opts.tac_vocab_file, 'rb')) + self.cutoff_len = opts.cutoff_len + + def create_tactic_batch(self, tok_seq): + mod_tok_seq = [] + if '' in self.tac_vocab: + for item in tok_seq: + mod_item = [self.tac_vocab[i] if i in self.tac_vocab else self.tac_vocab[''] for i in item] + mod_tok_seq.append(mod_item) + else: + for item in tok_seq: + mod_item = [self.tac_vocab[i] for i in item if i in self.tac_vocab] + mod_tok_seq.append(mod_item) + + max_len = min(max([len(item) for item in mod_tok_seq]), self.cutoff_len) + batch = [] + lens = [] + for item in mod_tok_seq: + idx = self.cutoff_len - 1 # ex: 29, for len 30 + lens.append(len(item[-idx:]) + 1) + new_item = [self.tac_vocab['']] + item[-idx:] + [self.tac_vocab['']]*(max_len-len(item[-idx:])-1) + batch.append(new_item) + + return torch.tensor(batch, device=self.opts.device), lens + + def embed_terms(self, environment, local_context, goal, tok_seq=None): + all_asts = list(chain([env['ast'] for env in chain(*environment)], [context['ast'] for context in chain(*local_context)], goal)) + all_embeddings = self.term_encoder(all_asts) + + batchsize = len(environment) + environment_embeddings = [] + j = 0 + for n in range(batchsize): + size = len(environment[n]) + environment_embeddings.append(torch.cat([torch.zeros(size, 3, device=self.opts.device), + all_embeddings[j : j + size]], dim=1)) + environment_embeddings[-1][:, 0] = 1.0 + j += size + + context_embeddings = [] + for n in range(batchsize): + size = len(local_context[n]) + context_embeddings.append(torch.cat([torch.zeros(size, 3, device=self.opts.device), + all_embeddings[j : j + size]], dim=1)) + context_embeddings[-1][:, 1] = 1.0 + j += size + + goal_embeddings = [] + for n in range(batchsize): + goal_embeddings.append(torch.cat([torch.zeros(3, device=self.opts.device), all_embeddings[j]], dim=0)) + goal_embeddings[-1][2] = 1.0 + j += 1 + goal_embeddings = torch.stack(goal_embeddings) + + if tok_seq: + tactic_batch, lens = self.create_tactic_batch(tok_seq) + tactic_embeddings = self.tactic_embedding(tactic_batch) + X = torch.nn.utils.rnn.pack_padded_sequence(tactic_embeddings, lens, batch_first=True, enforce_sorted=False) + tactic_seq_embeddings, _ = self.tactic_LSTM(X) + tactic_seq_embeddings, _ = torch.nn.utils.rnn.pad_packed_sequence(tactic_seq_embeddings, batch_first=True) + tactic_seq_embeddings = tactic_seq_embeddings[:, -1, :] + return environment_embeddings, context_embeddings, goal_embeddings, tactic_seq_embeddings + + + return environment_embeddings, context_embeddings, goal_embeddings + + + def forward(self, environment, local_context, goal, actions, teacher_forcing, tok_seq=None): + environment_embeddings, context_embeddings, goal_embeddings, seq_embeddings = \ + self.embed_terms(environment, local_context, goal, tok_seq) + environment = [{'idents': [v['qualid'] for v in env], + 'embeddings': environment_embeddings[i], + 'quantified_idents': [v['ast'].quantified_idents for v in env]} + for i, env in enumerate(environment)] + local_context = [{'idents': [v['ident'] for v in context], + 'embeddings': context_embeddings[i], + 'quantified_idents': [v['ast'].quantified_idents for v in context]} + for i, context in enumerate(local_context)] + goal = {'embeddings': goal_embeddings, 'quantified_idents': [g.quantified_idents for g in goal]} + asts, loss = self.tactic_decoder(environment, local_context, goal, actions, teacher_forcing, seq_embeddings) + return asts, loss + + + def beam_search(self, environment, local_context, goal, tok_seq=None): + environment_embeddings, context_embeddings, goal_embeddings, seq_embeddings = \ + self.embed_terms([environment], [local_context], [goal], [tok_seq]) + environment = {'idents': [v['qualid'] for v in environment], + 'embeddings': environment_embeddings[0], + 'quantified_idents': [v['ast'].quantified_idents for v in environment]} + local_context = {'idents': [v['ident'] for v in local_context], + 'embeddings': context_embeddings[0], + 'quantified_idents': [v['ast'].quantified_idents for v in local_context]} + goal = {'embeddings': goal_embeddings, 'quantified_idents': goal.quantified_idents} + asts = self.tactic_decoder.beam_search(environment, local_context, goal, seq_embeddings) + return asts diff --git a/src/coq/tactok/models/tactic_decoder.py b/src/coq/tactok/models/tactic_decoder.py new file mode 100644 index 0000000..3253dcd --- /dev/null +++ b/src/coq/tactok/models/tactic_decoder.py @@ -0,0 +1,438 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +import math +import random +import pdb +from copy import deepcopy +from tac_grammar import TerminalNode, NonterminalNode +from lark.lexer import Token + +class AvgLoss: + 'Maintaining the average of a set of losses' + + def __init__(self, device): + self.sum = torch.tensor(0., device=device) + self.num = 0 + + + def add(self, v): + self.sum += v + self.num += 1 + + def value(self): + return self.sum / self.num + + +class ContextReader(nn.Module): + + def __init__(self, opts): + super().__init__() + self.opts = opts + self.linear1 = nn.Linear(opts.hidden_dim + opts.term_embedding_dim + 3, opts.hidden_dim) + self.relu1 = nn.ReLU() + self.linear2 = nn.Linear(opts.hidden_dim, 1) + self.default_context = torch.zeros(self.opts.term_embedding_dim + 3, device=self.opts.device) + + + def forward(self, states, embeddings): + assert states.size(0) == len(embeddings) + context = [] + for state, embedding in zip(states, embeddings): + if embedding.size(0) == 0: # no premise + context.append(self.default_context) + else: + input = torch.cat([state.unsqueeze(0).expand(embedding.size(0), -1), embedding], dim=1) + weights = self.linear2(self.relu1(self.linear1(input))) + weights = F.softmax(weights, dim=0) + context.append(torch.matmul(embedding.t(), weights).squeeze()) + context = torch.stack(context) + return context + + +class ContextRetriever(nn.Module): + + def __init__(self, opts): + super().__init__() + self.opts = opts + self.linear1 = nn.Linear(opts.hidden_dim + opts.term_embedding_dim + 3, opts.hidden_dim) + self.relu1 = nn.ReLU() + self.linear2 = nn.Linear(opts.hidden_dim, 1) + + + def forward(self, state, embeddings): + input = torch.cat([state.unsqueeze(0).expand(embeddings.size(0), -1), embeddings], dim=1) + logits = self.linear2(self.relu1(self.linear1(input))) + return logits.view(logits.size(0)) + + +def clear_state(node): + del node.state + + +class TacticDecoder(nn.Module): + + def __init__(self, grammar, opts): + super().__init__() + self.opts = opts + self.grammar = grammar + self.symbol_embeddings = nn.Embedding(len(self.grammar.symbols), opts.symbol_dim) + self.production_rule_embeddings = nn.Embedding(len(self.grammar.production_rules), opts.embedding_dim) + self.lex_rule_embeddings = nn.Embedding(len(self.grammar.terminal_symbols), opts.embedding_dim) + self.default_action_embedding = torch.zeros(self.opts.embedding_dim, device=self.opts.device) + self.default_state = torch.zeros(self.opts.hidden_dim, device=self.opts.device) + self.controller = nn.GRUCell(2 * opts.embedding_dim + 2 * opts.term_embedding_dim + 6 + opts.hidden_dim + opts.symbol_dim + 512, opts.hidden_dim) + self.state_decoder = nn.Sequential(nn.Linear(opts.hidden_dim, opts.embedding_dim), nn.Tanh()) + self.context_reader = ContextReader(opts) + self.context_retriever = ContextRetriever(opts) + self.INT_classifier = nn.Sequential(nn.Linear(opts.hidden_dim, opts.hidden_dim // 2), + nn.ReLU(inplace=True), + nn.Linear(opts.hidden_dim // 2, 4)) + + self.hint_dbs = ['arith', 'zarith', 'algebra', 'real', 'sets', 'core', 'bool', 'datatypes', 'coc', 'set', 'zfc'] + self.HINT_DB_classifier = nn.Sequential(nn.Linear(opts.hidden_dim, opts.hidden_dim // 2), + nn.ReLU(inplace=True), + nn.Linear(opts.hidden_dim // 2, len(self.hint_dbs))) + + def action2embedding(self, action): + if isinstance(action, tuple): # a production rule + idx = self.grammar.production_rules.index(action) + return self.production_rule_embeddings(torch.LongTensor([idx]).to(self.opts.device)).squeeze() + else: # a token + idx = self.grammar.terminal_symbols.index(action) + return self.lex_rule_embeddings(torch.LongTensor([idx]).to(self.opts.device)).squeeze() + + + def gather_frontier_info(self, frontiers): + indice = [] # indice for incomplete ASTs + s_tm1 = [] + a_tm1 = [] + p_t = [] + symbols = [] + + for i, stack in enumerate(frontiers): + if stack == []: + continue + indice.append(i) + node = stack[-1] # the next node to expand + if node.pred is None: # root + assert node.parent is None + s_tm1.append(self.default_state) + a_tm1.append(self.default_action_embedding) + p_t.append(torch.cat([self.default_state, self.default_action_embedding])) + else: + s_tm1.append(node.pred.state) + a_tm1.append(self.action2embedding(node.pred.action)) + p_t.append(torch.cat([node.parent.state, self.action2embedding(node.parent.action)])) + symbols.append(node.symbol) + + if indice == []: # all trees are complete + return [], None, None, None, None + + symbol_indice = torch.LongTensor([self.grammar.symbols.index(s) for s in symbols]) + n_t = self.symbol_embeddings(symbol_indice.to(self.opts.device)) + s_tm1 = torch.stack(s_tm1) + a_tm1 = torch.stack(a_tm1) + p_t = torch.stack(p_t) + return indice, s_tm1, a_tm1, p_t, n_t + + + def initialize_trees(self, batchsize): + asts = [NonterminalNode(self.grammar.start_symbol, parent=None) for i in range(batchsize)] # partial results + frontiers = [[asts[i]] for i in range(batchsize)] # the stacks for DFS, whose top are the next nodes + return asts, frontiers + + + def expand_node_set_pred(self, node, rule, stack): + node.expand(rule) + + # updat the links to the predecessor + for c in node.children[::-1]: + if isinstance(c, Token): + continue + if stack != []: + stack[-1].pred = c + stack.append(c) + + if stack != []: + stack[-1].pred = node + + + def expand_nonterminal(self, node, expansion_step, nonterminal_expansion_step, actions_gt, teacher_forcing, stack): + # selcet a production rule and compute the loss + applicable_rules = self.grammar.get_applicable_rules(node.symbol) + + if teacher_forcing: + logits = torch.matmul(self.production_rule_embeddings.weight[applicable_rules], self.state_decoder(node.state)) + action_idx = actions_gt[expansion_step] + rule = self.grammar.production_rules[action_idx] # expand the tree using the ground truth action + action_gt_onehot = torch.LongTensor([applicable_rules.index(action_idx)]).to(self.opts.device) + loss = F.cross_entropy(logits.unsqueeze(0), action_gt_onehot) + + else: + logits = torch.matmul(self.production_rule_embeddings.weight, self.state_decoder(node.state)) + rule_idx = applicable_rules[logits[applicable_rules].argmax().item()] + rule = self.grammar.production_rules[rule_idx] + if nonterminal_expansion_step < len(actions_gt): + action_idx = actions_gt[nonterminal_expansion_step] + action_gt_onehot = torch.LongTensor([action_idx]).to(self.opts.device) + loss = F.cross_entropy(logits.unsqueeze(0), action_gt_onehot) + else: + loss = 0. + + if expansion_step > self.opts.size_limit: # end the generation process asap + rule_idx = applicable_rules[0] + rule = self.grammar.production_rules[rule_idx] + + self.expand_node_set_pred(node, rule, stack) + + return loss + + + def expand_terminal(self, node, expansion_step, environment, local_context, goal, actions_gt, teacher_forcing): + loss = 0. + if teacher_forcing: + token_gt = actions_gt[expansion_step] + + if node.symbol in ['QUALID', 'LOCAL_IDENT']: + if node.symbol == 'QUALID': + candidates = environment['idents'] + local_context['idents'] + else: + candidates = local_context['idents'] + if candidates == []: + token = random.choice(['H'] + goal['quantified_idents']) + else: + if node.symbol == 'QUALID': + candidate_embeddings = torch.cat([environment['embeddings'], local_context['embeddings']]) + else: + candidate_embeddings = local_context['embeddings'] + context_scores = self.context_retriever(node.state, candidate_embeddings) + if teacher_forcing: + target = torch.zeros_like(context_scores) + if token_gt in candidates: + target[candidates.index(token_gt)] = 1.0 + loss = F.binary_cross_entropy_with_logits(context_scores, target) + else: + token = candidates[context_scores.argmax()] + + elif node.symbol in 'INT': + cls = self.INT_classifier(node.state) + if teacher_forcing: + cls_gt = torch.LongTensor([int(token_gt) - 1]).to(self.opts.device) + loss = F.cross_entropy(cls.unsqueeze(0), cls_gt) + else: + token = str(cls.argmax().item() + 1) + + elif node.symbol == 'HINT_DB': + cls = self.HINT_DB_classifier(node.state) + if teacher_forcing: + cls_gt = torch.LongTensor([self.hint_dbs.index(token_gt)]).to(self.opts.device) + loss = F.cross_entropy(cls.unsqueeze(0), cls_gt) + else: + token = self.hint_dbs[cls.argmax().item()] + + elif node.symbol == 'QUANTIFIED_IDENT': + if goal['quantified_idents'] == []: + candidates = ['x'] + else: + candidates = goal['quantified_idents'] + token = random.choice(candidates) + + # generadddte a token with the lex rule + node.expand(token_gt if teacher_forcing else token) + + return loss + + + def expand_partial_tree(self, node, expansion_step, nonterminal_expansion_step, environment, local_context, goal, actions_gt, + teacher_forcing, stack): + assert node.state is not None + if isinstance(node, NonterminalNode): + return self.expand_nonterminal(node, expansion_step, nonterminal_expansion_step, actions_gt, teacher_forcing, stack) + else: + return self.expand_terminal(node, expansion_step, environment, local_context, goal, actions_gt, teacher_forcing) + + + def forward(self, environment, local_context, goal, actions, teacher_forcing, seq_embeddings=None): + if not teacher_forcing: + # when train without teacher forcing, only consider the expansion of non-terminal nodes + actions = [[a for a in act if isinstance(a, int)] for act in actions] + + loss = AvgLoss(self.opts.device) + + # initialize the trees + batchsize = goal['embeddings'].size(0) + asts, frontiers = self.initialize_trees(batchsize) + + # expand the trees in a depth-first order + expansion_step = 0 + nonterminal_expansion_step = [0 for i in range(batchsize)] + while True: + # in each iteration, compute the state of the frontier nodes and expand them + # collect inputs from all partial trees: s_{t-1}, a_{t-1}, p_t, n_t + indice, s_tm1, a_tm1, p_t, n_t = self.gather_frontier_info(frontiers) + if indice == []: # all trees are complete + break + + r = [torch.cat([environment[i]['embeddings'], local_context[i]['embeddings']], dim=0) for i in indice] + u_t = self.context_reader(s_tm1, r) + + states = self.controller(torch.cat([a_tm1, goal['embeddings'][indice], u_t, p_t, n_t, seq_embeddings[indice]], dim=1), s_tm1) + + # store states and expand nodes + for j, idx in enumerate(indice): + stack = frontiers[idx] + node = stack.pop() + node.state = states[j] + g = {k: v[idx] for k, v in goal.items()} + loss.add(self.expand_partial_tree(node, expansion_step, nonterminal_expansion_step[idx], + environment[idx], local_context[idx], g, actions[idx], teacher_forcing, stack)) + if isinstance(node, NonterminalNode): + nonterminal_expansion_step[idx] += 1 + + expansion_step += 1 + + for ast in asts: + ast.traverse_pre(clear_state) + + return asts, loss.value() + + + def duplicate(self, ast, stack): + old2new = {} + def recursive_duplicate(node, parent=None): + if isinstance(node, Token): + new_node = deepcopy(node) + old2new[node] = new_node + return new_node + elif isinstance(node, TerminalNode): + new_node = TerminalNode(node.symbol, parent) + new_node.token = node.token + else: + assert isinstance(node, NonterminalNode) + new_node = NonterminalNode(node.symbol, parent) + + old2new[node] = new_node + new_node.action = node.action + if node.pred is None: + new_node.pred = None + else: + new_node.pred = old2new[node.pred] + new_node.state = node.state + if isinstance(node, NonterminalNode): + for c in node.children: + new_node.children.append(recursive_duplicate(c, new_node)) + return new_node + + new_ast = recursive_duplicate(ast) + new_stack = [old2new[node] for node in stack] + return new_ast, new_stack + + + def beam_search(self, environment, local_context, goal, seq_embeddings=None): + # initialize the trees in the beam + assert goal['embeddings'].size(0) == 1 # only support batchsize == 1 + beam, frontiers = self.initialize_trees(1) + log_likelihood = [0.] # the (unnormalized) objective function maximized by the beam search + complete_trees = [] # the complete ASTs generated during the beam search + + expansion_step = 0 + while True: + # collect inputs from all partial trees + indice, s_tm1, a_tm1, p_t, n_t = self.gather_frontier_info(frontiers) + # check if there are complete trees + for i in range(len(beam)): + if i not in indice: + normalized_log_likelihood = log_likelihood[i] / (expansion_step ** self.opts.lens_norm) # length normalization + beam[i].traverse_pre(clear_state) + complete_trees.append((beam[i], normalized_log_likelihood)) + if indice == []: # all trees are complete, terminate the beam search + break + + r = [torch.cat([environment['embeddings'], local_context['embeddings']], dim=0) for i in indice] + u_t = self.context_reader(s_tm1, r) + + states = self.controller(torch.cat([a_tm1, goal['embeddings'].expand(len(indice), -1), u_t, p_t, n_t, seq_embeddings.expand(len(indice), -1)], dim=1), s_tm1) + + # compute the log likelihood and pick the top candidates + beam_candidates = [] + for j, idx in enumerate(indice): + stack = frontiers[idx] + node = stack[-1] + node.state = states[j] + + if isinstance(node, NonterminalNode): + applicable_rules = self.grammar.get_applicable_rules(node.symbol) + if expansion_step > self.opts.size_limit: # end the generation process asap + beam_candidates.append((idx, log_likelihood[i], applicable_rules[0])) + else: + logits = torch.matmul(self.production_rule_embeddings.weight[applicable_rules], self.state_decoder(node.state)) + log_cond_prob = logits - logits.logsumexp(dim=0) + for n, cand in enumerate(applicable_rules): + beam_candidates.append((idx, log_likelihood[idx] + log_cond_prob[n].item(), cand)) + + elif node.symbol in ['QUALID', 'LOCAL_IDENT']: + if node.symbol == 'QUALID': + candidates = environment['idents'] + local_context['idents'] + else: + candidates = local_context['idents'] + if candidates == []: + candidates = ['H'] + goal['quantified_idents'] + log_cond_prob = - math.log(len(candidates)) + for cand in candidates: + beam_candidates.append((idx, log_likelihood[idx] + log_cond_prob, cand)) + else: + if node.symbol == 'QUALID': + candidate_embeddings = torch.cat([environment['embeddings'], local_context['embeddings']]) + else: + candidate_embeddings = local_context['embeddings'] + context_scores = self.context_retriever(node.state, candidate_embeddings) + log_cond_prob = context_scores - context_scores.logsumexp(dim=0) + for n, cand in enumerate(candidates): + beam_candidates.append((idx, log_likelihood[idx] + log_cond_prob[n].item(), cand)) + + elif node.symbol == 'INT': + cls = self.INT_classifier(node.state) + log_cond_prob = cls - cls.logsumexp(dim=0) + for n in range(cls.size(0)): + beam_candidates.append((idx, log_likelihood[idx] + log_cond_prob[n].item(), str(n + 1))) + + elif node.symbol == 'HINT_DB': + cls = self.HINT_DB_classifier(node.state) + log_cond_prob = cls - cls.logsumexp(dim=0) + for n in range(cls.size(0)): + beam_candidates.append((idx, log_likelihood[idx] + log_cond_prob[n].item(), self.hint_dbs[n])) + + elif node.symbol == 'QUANTIFIED_IDENT': + if len(goal['quantified_idents']) > 0: + candidates = list(goal['quantified_idents']) + else: + candidates = ['x'] + log_cond_prob = - math.log(len(candidates)) + for cand in candidates: + beam_candidates.append((idx, log_likelihood[idx] + log_cond_prob, cand)) + + # expand the nodes and update the beam + beam_candidates = sorted(beam_candidates, key=lambda x: x[1], reverse=True)[:self.opts.beam_width] + new_beam = [] + new_frontiers = [] + new_log_likelihood = [] + for idx, log_cond_prob, action in beam_candidates: + ast, stack = self.duplicate(beam[idx], frontiers[idx]) + node = stack.pop() + if isinstance(action, int): # expand a nonterimial node + rule = self.grammar.production_rules[action] + self.expand_node_set_pred(node, rule, stack) + else: # expand a terminal node + node.expand(action) + new_beam.append(ast) + new_frontiers.append(stack) + new_log_likelihood.append(log_likelihood[idx] + log_cond_prob) + beam = new_beam + frontiers = new_frontiers + log_likelihood = new_log_likelihood + expansion_step += 1 + + complete_trees = sorted(complete_trees, key=lambda x: x[1], reverse=True) # pick the top ASTs + return [t[0] for t in complete_trees[:self.opts.num_tactic_candidates]] + diff --git a/src/coq/tactok/models/term_encoder.py b/src/coq/tactok/models/term_encoder.py new file mode 100644 index 0000000..cfc52ba --- /dev/null +++ b/src/coq/tactok/models/term_encoder.py @@ -0,0 +1,187 @@ +import torch +import torch.nn as nn +import torch.nn.functional as F +import math +from collections import defaultdict +from time import time +from itertools import chain +from lark.tree import Tree +import os +from gallina import traverse_postorder +import pdb + + +nonterminals = [ + 'constr__constr', + 'constructor_rel', + 'constructor_var', + 'constructor_meta', + 'constructor_evar', + 'constructor_sort', + 'constructor_cast', + 'constructor_prod', + 'constructor_lambda', + 'constructor_letin', + 'constructor_app', + 'constructor_const', + 'constructor_ind', + 'constructor_construct', + 'constructor_case', + 'constructor_fix', + 'constructor_cofix', + 'constructor_proj', + 'constructor_ser_evar', + 'constructor_prop', + 'constructor_set', + 'constructor_type', + 'constructor_ulevel', + 'constructor_vmcast', + 'constructor_nativecast', + 'constructor_defaultcast', + 'constructor_revertcast', + 'constructor_anonymous', + 'constructor_name', + 'constructor_constant', + 'constructor_mpfile', + 'constructor_mpbound', + 'constructor_mpdot', + 'constructor_dirpath', + 'constructor_mbid', + 'constructor_instance', + 'constructor_mutind', + 'constructor_letstyle', + 'constructor_ifstyle', + 'constructor_letpatternstyle', + 'constructor_matchstyle', + 'constructor_regularstyle', + 'constructor_projection', + 'bool', + 'int', + 'names__label__t', + 'constr__case_printing', + 'univ__universe__t', + 'constr__pexistential___constr__constr', + 'names__inductive', + 'constr__case_info', + 'names__constructor', + 'constr__prec_declaration___constr__constr____constr__constr', + 'constr__pfixpoint___constr__constr____constr__constr', + 'constr__pcofixpoint___constr__constr____constr__constr', +] + + +class InputOutputUpdateGate(nn.Module): + + def __init__(self, hidden_dim, nonlinear): + super().__init__() + self.nonlinear = nonlinear + k = 1. / math.sqrt(hidden_dim) + self.W = nn.Parameter(torch.Tensor(hidden_dim, len(nonterminals) + hidden_dim)) + nn.init.uniform_(self.W, -k, k) + self.b = nn.Parameter(torch.Tensor(hidden_dim)) + nn.init.uniform_(self.b, -k, k) + + + def forward(self, xh): + return self.nonlinear(F.linear(xh, self.W, self.b)) + + +class ForgetGates(nn.Module): + + def __init__(self, hidden_dim, opts): + super().__init__() + self.hidden_dim = hidden_dim + self.opts = opts + k = 1. / math.sqrt(hidden_dim) + # the weight for the input + self.W_if = nn.Parameter(torch.Tensor(hidden_dim, len(nonterminals))) + nn.init.uniform_(self.W_if, -k, k) + # the weight for the hidden + self.W_hf = nn.Parameter(torch.Tensor(hidden_dim, hidden_dim)) + nn.init.uniform_(self.W_hf, -k, k) + # the bias + self.b_f = nn.Parameter(torch.Tensor(hidden_dim)) + nn.init.uniform_(self.b_f, -k, k) + + + def forward(self, x, h_children, c_children): + c_remain = torch.zeros(x.size(0), self.hidden_dim).to(self.opts.device) + + Wx = F.linear(x, self.W_if) + all_h = list(chain(*h_children)) + if all_h == []: + return c_remain + Uh = F.linear(torch.stack(all_h), self.W_hf, self.b_f) + i = 0 + for j, h in enumerate(h_children): + if h == []: + continue + f_gates = torch.sigmoid(Wx[j] + Uh[i : i + len(h)]) + i += len(h) + c_remain[j] = (f_gates * torch.stack(c_children[j])).sum(dim=0) + + return c_remain + + +class TermEncoder(nn.Module): + + def __init__(self, opts): + super().__init__() + self.opts = opts + self.input_gate = InputOutputUpdateGate(opts.term_embedding_dim, nonlinear=torch.sigmoid) + self.forget_gates = ForgetGates(opts.term_embedding_dim, opts) + self.output_gate = InputOutputUpdateGate(opts.term_embedding_dim, nonlinear=torch.sigmoid) + self.update_cell = InputOutputUpdateGate(opts.term_embedding_dim, nonlinear=torch.tanh) + + + def forward(self, term_asts): + # the height of a node determines when it can be processed + height2nodes = defaultdict(set) + + def get_height(node): + height2nodes[node.height].add(node) + + for ast in term_asts: + traverse_postorder(ast, get_height) + + memory_cells = {} # node -> memory cell + hidden_states = {} # node -> hidden state + #return torch.zeros(len(term_asts), self.opts.term_embedding_dim).to(self.opts.device) + + # compute the embedding for each node + for height in sorted(height2nodes.keys()): + nodes_at_height = list(height2nodes[height]) + # sum up the hidden states of the children + h_sum = [] + c_remains = [] + x = torch.zeros(len(nodes_at_height), len(nonterminals), device=self.opts.device) \ + .scatter_(1, torch.tensor([nonterminals.index(node.data) for node in nodes_at_height], + device=self.opts.device).unsqueeze(1), 1.0) + + h_sum = torch.zeros(len(nodes_at_height), self.opts.term_embedding_dim).to(self.opts.device) + h_children = [] + c_children = [] + for j, node in enumerate(nodes_at_height): + h_children.append([]) + c_children.append([]) + for c in node.children: + h = hidden_states[c] + h_sum[j] += h + h_children[-1].append(h) + c_children[-1].append(memory_cells[c]) + c_remains = self.forget_gates(x, h_children, c_children) + + # gates + xh = torch.cat([x, h_sum], dim=1) + i_gate = self.input_gate(xh) + o_gate = self.output_gate(xh) + u = self.update_cell(xh) + cells = i_gate * u + c_remains + hiddens = o_gate * torch.tanh(cells) + + + for i, node in enumerate(nodes_at_height): + memory_cells[node] = cells[i] + hidden_states[node] = hiddens[i] + + return torch.stack([hidden_states[ast] for ast in term_asts]) diff --git a/src/coq/tactok/options.ml b/src/coq/tactok/options.ml new file mode 100644 index 0000000..d8386f5 --- /dev/null +++ b/src/coq/tactok/options.ml @@ -0,0 +1,15 @@ +(* --- Options for Decompiler with TacTok --- *) + +let default_beam_width = 10 +let opt_beam_width = ref default_beam_width +let _ = Goptions.declare_int_option { + Goptions.optdepr = false; + Goptions.optname = "Beam width"; + Goptions.optkey = ["beam"]; + Goptions.optread = (fun () -> get_beam_width ()); + Goptions.optwrite = (fun o -> + let wid = o in + set_beam_width wid) } + +let set_beam_width = (:=) opt_beam_width +let get_beam_width () = !opt_beam_width \ No newline at end of file diff --git a/src/coq/tactok/options.mli b/src/coq/tactok/options.mli new file mode 100644 index 0000000..dddc748 --- /dev/null +++ b/src/coq/tactok/options.mli @@ -0,0 +1,10 @@ +(* --- Options for Decompiler with TacTok --- *) + +(* + * Beam width is the number of tactics TacTok will predict in order + * of probability + *) + +val default_beam_width : int +val set_beam_width : int -> unit +val get_beam_width : unit -> int diff --git a/src/coq/tactok/tac_grammar.py b/src/coq/tactok/tac_grammar.py new file mode 100644 index 0000000..87e138a --- /dev/null +++ b/src/coq/tactok/tac_grammar.py @@ -0,0 +1,290 @@ +from glob import glob +import re +from io import StringIO +from lark import Lark, Transformer +from lark.lexer import Token +import logging +logging.basicConfig(level=logging.DEBUG) +import pdb +from progressbar import ProgressBar +import sys + + +class RuleBuilder(Transformer): + + def symbol(self, children): + assert len(children) == 1 + if children[0].type == 'TERMINAL': + assert children[0].value.isupper() + return children[0].value + elif children[0].type == 'NONTERMINAL': + assert children[0].value.islower() + return children[0].value + else: + assert children[0].type in ['ESCAPED_STRING', 'REGEXP'] + return children[0].value + + + def rhs(self, children): + return children + + + def nonterminal_rule(self, children): + assert children[0].type == 'NONTERMINAL' + return [(children[0].value, c) for c in children[1:]] + + + def terminal_rule(self, children): + assert children[0].type == 'TERMINAL' + return [(children[0].value, children[1].value)] + + + def rule(self, children): + assert len(children) == 1 + return children[0] + + +class CFG: + + def __init__(self, grammar_file, start_symbol): + self.terminal_symbols = [] + self.nonterminal_symbols = [] + self.production_rules = [] + self.start_symbol = start_symbol + + meta_grammar = ''' + rule : nonterminal_rule + | terminal_rule + nonterminal_rule : "!"? NONTERMINAL ":" rhs ("|" rhs)* + NONTERMINAL : /[a-z0-9_]+/ + ALIAS : /[a-z_]+/ + symbol : TERMINAL + | NONTERMINAL + | ESCAPED_STRING + | REGEXP + rhs : symbol* ["->" ALIAS] + terminal_rule : TERMINAL ":" ESCAPED_STRING + | TERMINAL ":" REGEXP + TERMINAL : /[A-Z_]+/ + REGEXP : "/" STRING_INNER+ "/" + %import common.STRING_INNER + %import common.ESCAPED_STRING + %import common.WS + %ignore WS + ''' + meta_parser = Lark(meta_grammar, start='rule', parser='earley') + t = RuleBuilder() + self.ebnf = open(grammar_file).read() + + for rule_ebnf in self.ebnf.split('\n\n'): + if rule_ebnf.startswith('%'): + continue + rules = t.transform(meta_parser.parse(rule_ebnf)) + if rules[0][0].islower(): + self.nonterminal_symbols.append(rules[0][0]) + self.production_rules.extend(rules) + else: + self.terminal_symbols.append(rules[0][0]) + self.symbols = self.nonterminal_symbols + self.terminal_symbols + + + self.parser = Lark(StringIO(self.ebnf), start=self.start_symbol, parser='earley', debug=True) + + + def get_applicable_rules(self, symbol): + return [i for i, rule in enumerate(self.production_rules) if rule[0] == symbol] + + + def __str__(self): + return self.ebnf + + +class Node: + + def __init__(self, symbol, parent): + self.symbol = symbol + self.parent = parent + self.pred = None # predecessor in depth-first search + self.state = None # the hidden state of GRU + self.action = None # the production rule used to expand this node + + +class NonterminalNode(Node): + + def __init__(self, symbol, parent): + super().__init__(symbol, parent) + self.children = [] + + + def __str__(self): + return 'NonterminalNode(%s, children=%s)' % (self.symbol, str(self.children)) + + + def __repr__(self): + return str(self) + + + def expand(self, rule): + assert rule[0] == self.symbol and self.action is None and self.children == [] + self.action = rule + for entry in rule[1]: + if entry.startswith('"') and entry.endswith('"'): # token + self.children.append(Token('literal', entry[1:-1])) + elif entry.islower(): # nonterminal symbol + self.children.append(NonterminalNode(entry, self)) + else: # terminal symbol + assert entry.isupper() + self.children.append(TerminalNode(entry, self)) + + + def to_tokens(self): + assert self.action is not None + fields = [] + for r, c in zip(self.action[1], self.children): + if isinstance(c, Token): + assert c.value == r[1:-1] + fields.append(c.value) + elif isinstance(c, NonterminalNode): + assert c.symbol == r + fields.append(c.to_tokens()) + else: + assert isinstance(c, TerminalNode) + fields.append(c.token) + return ' '.join(fields).strip() + + + def traverse_pre(self, callback): + callback(self) + for c in self.children: + if isinstance(c, Node): + c.traverse_pre(callback) + + + def height(self): + return 1 + max([-1] + [0 if isinstance(c, Token) else c.height() for c in self.children]) + + + def num_tokens(self): + n = 0 + for c in self.children: + if isinstance(c, Token) or isinstance(c, TerminalNode): + n += 1 + else: + assert isinstance(c, NonterminalNode) + n += c.num_tokens() + return n + + def has_argument(self): + result = False + for c in self.children: + if isinstance(c, TerminalNode): + return True + if isinstance(c, NonterminalNode): + result = result or c.has_argument() + return result + + +class TerminalNode(Node): + + def __init__(self, symbol, parent): + super().__init__(symbol, parent) + self.action = symbol + self.token = None + + + def expand(self, token): + self.token = token + + + def __str__(self): + return 'TerminalNode(%s, token=%s)' % (self.symbol, str(self.action)) + + + def __repr__(self): + return str(self) + + + def traverse_pre(self, callback): + callback(self) + + + def height(self): + return 0 + + +def find_rule(symbol, children, production_rules): + matches = [] + for rule in production_rules: + if rule[0] != symbol: + continue + if len(rule[1]) != len(children): + continue + for r, c in zip(rule[1], children): + if isinstance(c, Token): + if not isinstance(r, str): + break + if not (r.startswith('"') and r.endswith('"')): + break + if c.value != r[1:-1]: + break + elif isinstance(c, TerminalNode): + if not r.isupper() or r != c.symbol: + break + elif isinstance(c, NonterminalNode): + if not r.islower() or r != c.symbol: + break + else: + raise TypeError + else: + matches.append(rule) + assert len(matches) == 1 + return matches[0] + + +class TreeBuilder(Transformer): + + def __init__(self, grammar): + super().__init__() + self.grammar = grammar + + + def __default__(self, symbol, children, meta): + node = NonterminalNode(symbol, parent=None) + + for c in children: + if isinstance(c, Token): + if c.type in self.grammar.terminal_symbols: + t = TerminalNode(c.type, parent=None) + t.token = c.value + c = t + else: + assert isinstance(c, NonterminalNode) and c.parent is None + c.parent = node + node.children.append(c) + + node.action = find_rule(symbol, node.children, self.grammar.production_rules) + return node + + +if __name__ == '__main__': + grammar = CFG('tactics.ebnf', 'tactic_expr') + print(grammar) + + oup = open('fails.txt', 'wt') + num_failed = 0 + num_succeeded = 0 + + for tac_str in open('correct_tacs.txt'): + tac_str = tac_str.strip() + #assert tac_str.endswith('.') + #tac_str = tac_str[:-1] + try: + tree = grammar.parser.parse(tac_str) + pdb.set_trace() + num_succeeded += 1 + except Exception as ex: + oup.write(tac_str + '\n') + num_failed += 1 + + print(num_succeeded, num_failed) + diff --git a/src/coq/tactok/tactics.ebnf b/src/coq/tactok/tactics.ebnf new file mode 100644 index 0000000..3f2d056 --- /dev/null +++ b/src/coq/tactok/tactics.ebnf @@ -0,0 +1,135 @@ +!tactic_expr : intro + | "apply" term_commalist1 reduced_in_clause + | "auto" using_clause with_hint_dbs + | "rewrite" rewrite_term_list1 in_clause + | "simpl" in_clause + | "unfold" qualid_list1 in_clause + | destruct + | induction + | "elim" QUALID + | "split" + | "assumption" + | trivial + | "reflexivity" + | "case" QUALID + | clear + | "subst" local_ident_list + | "generalize" term_list1 + | "exists" LOCAL_IDENT + | "red" in_clause + | "omega" + | discriminate + | inversion + | simple_induction + | constructor + | "congruence" + | "left" + | "right" + | "ring" + | "symmetry" + | "f_equal" + | "tauto" + | "revert" local_ident_list1 + | "specialize" "(" LOCAL_IDENT QUALID ")" + | "idtac" + | "hnf" in_clause + | inversion_clear + | contradiction + | "injection" LOCAL_IDENT + | "exfalso" + | "cbv" + | "contradict" LOCAL_IDENT + | "lia" + | "field" + | "easy" + | "cbn" + | "exact" QUALID + | "intuition" + | "eauto" using_clause with_hint_dbs + +LOCAL_IDENT : /[A-Za-z_][A-Za-z0-9_']*/ + +QUANTIFIED_IDENT : /[A-Za-z_][A-Za-z0-9_']*/ + +INT : /1|2|3|4/ + +QUALID : /([A-Za-z_][A-Za-z0-9_']*\.)*[A-Za-z_][A-Za-z0-9_']*/ + +HINT_DB : /arith|zarith|algebra|real|sets|core|bool|datatypes|coc|set|zfc/ + +!local_ident_list : + | LOCAL_IDENT local_ident_list + +!local_ident_list1 : LOCAL_IDENT + | LOCAL_IDENT local_ident_list1 + +!qualid_list1 : QUALID + | QUALID "," qualid_list1 + +!term_list1 : QUALID + | QUALID term_list1 + +!term_commalist1 : QUALID + | QUALID "," term_commalist1 + +!hint_db_list1 : HINT_DB + | HINT_DB hint_db_list1 + +!reduced_in_clause : + | "in" LOCAL_IDENT + +!in_clause : + | "in" LOCAL_IDENT + | "in" "|- *" + | "in" "*" + +!at_clause : + | "at" INT + +!using_clause : + | "using" qualid_list1 + +!with_hint_dbs : + | "with" hint_db_list1 + | "with" "*" + +!intro : "intro" + | "intros" + +!rewrite_term : QUALID + | "->" QUALID + | "<-" QUALID + +!rewrite_term_list1 : rewrite_term + | rewrite_term "," rewrite_term_list1 + +!destruct : "destruct" term_commalist1 + +!induction : "induction" LOCAL_IDENT + | "induction" INT + +!trivial : "trivial" + +!clear : "clear" + | "clear" local_ident_list1 + +!discriminate : "discriminate" + | "discriminate" LOCAL_IDENT + +!inversion : "inversion" LOCAL_IDENT + | "inversion" INT + +!simple_induction : "simple induction" QUANTIFIED_IDENT + | "simple induction" INT + +!constructor : "constructor" + | "constructor" INT + +!inversion_clear : "inversion_clear" LOCAL_IDENT + | "inversion_clear" INT + +!contradiction : "contradiction" + | "contradiction" LOCAL_IDENT + +%import common.WS +%ignore WS diff --git a/src/coq/tactok/tactok.ml b/src/coq/tactok/tactok.ml new file mode 100644 index 0000000..5f80be7 --- /dev/null +++ b/src/coq/tactok/tactok.ml @@ -0,0 +1,43 @@ +open Names +open Constr +open Environ +open Envutils +open Pp +open Equtils +open Proputils +open Indutils +open Funutils +open Inference +open Vars +open Utilities +open Zooming +open Nameutils +open Ltac_plugin +open Stateutils +open Lymp +open Ser_names + +let py = init "." +let agent_utils = get_module py "agent_utils" +let prover = get_module py "prover" + +(* Follow this format *) +(* let module = Lymp.get_module py in +let obj = Lymp.get_ref module in +let result = Lymp.get_ obj in *) + +let parse_script script = + get_list agent_utils "parse_script" [Pylist script] + +let import_model () = + get_ref agent_utils "import_model" [] + +let beam_search env prev goal = + let model = import_model () in + let script = parse_script prev in (* need to reverse prev *) + (* ser api calls to serialize *) + let ser_env = pp_format env in + let ser_goal = pp_format goal in + let filter_env = get_ref agent_utils "filter_env" [Pyref ser_env] in + let local_context, parsed_goal = get_ref agent_utils "parse_goal" [Pyref ser_goal] in + get_list prover "beam_search" [Pyref model; Pyref filter_env; Pyref local_context; Pyref parsed_goal; Pylist script] in \ No newline at end of file diff --git a/src/coq/tactok/tactok.mli b/src/coq/tactok/tactok.mli new file mode 100644 index 0000000..f2b274f --- /dev/null +++ b/src/coq/tactok/tactok.mli @@ -0,0 +1,20 @@ +open Names +open Constr +open Environ +open Envutils +open Pp +open Equtils +open Proputils +open Indutils +open Funutils +open Inference +open Vars +open Utilities +open Zooming +open Nameutils +open Ltac_plugin +open Stateutils +open Lymp +open Ser_names + +val beam_search : env -> string list -> types -> string list diff --git a/src/coq/tactok/token_vocab.pickle b/src/coq/tactok/token_vocab.pickle new file mode 100644 index 0000000000000000000000000000000000000000..ca73c5b7c33f77a774fcb35fec7d1e4e8250005f GIT binary patch literal 361154 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

C~FNqeF>LzX2jp9wYon` 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

1L{`RLH6hV3fZ+JD|Bfwg;@sWVl-; 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 literal 0 HcmV?d00001 From 1776cb1c181245bf1ab858c1785bfa01e1f0007f Mon Sep 17 00:00:00 2001 From: efirst Date: Tue, 5 Oct 2021 13:47:27 -0400 Subject: [PATCH 37/39] removed some DS stores hopefully --- deps/.DS_Store | Bin 6148 -> 0 bytes src/coq/tactok/.DS_Store | Bin 6148 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 deps/.DS_Store delete mode 100644 src/coq/tactok/.DS_Store diff --git a/deps/.DS_Store b/deps/.DS_Store deleted file mode 100644 index ba939f3e7113151372ce365d2182e9efbd34bc3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!A{#i5S)(pxGyNL9oE$qMw)8~w2v=A+he~|&+yAFM&33e^PuKnJ>j6UFfOeuDAWc(HE3o7Gjc@<|xjLf_E zDoe}C_wQ9>rMbHH#%tku>z#(9Vj5OaH7N(t_=MjMqG}X7`>-goCp(Id(&6;1y}4K9 zRg~t#u}MyoAws?!r+HFL2gM{$N;6JqJ9wVfS$k_X>wWC^yL#LA=UqMP_x-Nk+3wBf zEwA&wxBL10^5*;O$Nc9nOTNPI)X0XzN4SOYLLQRxB8#yS9^!?m*WozNiu@ZgA3umk z5fKK20byWC47j7mTVK+AGL0}G4E#R~@cE#jjDf@2qB%Oym=XZkgxd>|d4}I}9Aw z7SRJyHWg@7l`AonO^08*xWHj;(WaAf#fNe;D_5Z?GdsrDCY)4YQCeX@82FO`uKgfw zzW+b{z5X{r(g*{>!0Ti{HTT2)0oLa3)`eB_U8|wzP!^7>Ek32dFjp~R`6_+~H3Gk8 W0~k20Ey4qlKLUmZX@r5LGVlOCNo#We diff --git a/src/coq/tactok/.DS_Store b/src/coq/tactok/.DS_Store deleted file mode 100644 index 86ee6639d0af80e6263bb55fe3f11bd0e70c2418..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!A`&{SEyizrf#d zW_KYW=*<{IW|EmV%+73?SF+16#&~NS)EO%?#sny0t_bEE!FALX$=OIAkn24nmiUuo z=ts(5$)>=6WB}jYCL1ut0@h>8@9)DOMq!fHYM(rpFKldX2~iTIozk7#R}(k&(s9!A zMmPBB!b|(U^)Ho*7QW|Sg}q6qymzYN)C=R@NEe4e4^nQg!#GfrmKw)FqW5vlf)GVf z?363h>0zT@mG#=utSYC?X00lZn~mA5DE1HPC+FS4)ARIY_WEX+oG0pjz`=9>@_1H=F^us#gf6HaWePfOGZF+dFb5(9WXNKiz_ zVrEbu9bohb09b&q7VvSFz#3`Mv6vZz6%cMp0Zl2lBL+9+5SKR3v6vY&<&4|mgWD%_ zJE3s>bl6|&bjBTnWQhS{V3`4&{Xoii|DXLl|LY_&!~ij{o(%9p+ika?H+#3PbcuJZ t1nq*NU|wc$Q38&>iXj)T;tHr1h)Z+;9gCSkh=9-^0ZjuLV&G31_yT;;SWf@| From 740df173ac1f22007aa0428d577282c4c710712d Mon Sep 17 00:00:00 2001 From: efirst Date: Fri, 15 Oct 2021 12:42:17 -0400 Subject: [PATCH 38/39] fixing modules --- .gitmodules | 2 +- deps/fundamental-arithmetics | 1 + fundamental-arithmetics | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) create mode 160000 deps/fundamental-arithmetics create mode 160000 fundamental-arithmetics diff --git a/.gitmodules b/.gitmodules index e85e297..0f6970d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "plugin/deps/fundamental-arithmetics"] +[submodule "deps/fundamental-arithmetics"] path = deps/fundamental-arithmetics url = https://github.com/coq-contribs/fundamental-arithmetics diff --git a/deps/fundamental-arithmetics b/deps/fundamental-arithmetics new file mode 160000 index 0000000..8976d4b --- /dev/null +++ b/deps/fundamental-arithmetics @@ -0,0 +1 @@ +Subproject commit 8976d4ba6a5c53b7eb25d08921e592d200189431 diff --git a/fundamental-arithmetics b/fundamental-arithmetics new file mode 160000 index 0000000..8976d4b --- /dev/null +++ b/fundamental-arithmetics @@ -0,0 +1 @@ +Subproject commit 8976d4ba6a5c53b7eb25d08921e592d200189431 From 52fad767b2ccdee8f2785ea9aa23015bdd20266c Mon Sep 17 00:00:00 2001 From: efirst Date: Tue, 19 Oct 2021 14:09:59 -0400 Subject: [PATCH 39/39] adding in sexp --- .gitmodules | 3 --- coq/FundamentalArithmetics.v | 16 ---------------- coq/Test.v | 1 - deps/fundamental-arithmetics | 1 - fundamental-arithmetics | 1 - src/coq/decompiler/decompiler.ml | 18 +++++++++++------- src/coq/dune | 1 + src/coq/tactok/agent_utils.py | 3 ++- src/coq/tactok/coq_gym.yml | 16 ++++++++++++++++ src/coq/tactok/dune | 16 ++++++++++++++++ src/coq/tactok/tactok.ml | 16 +++++++++------- src/coq/tactok/tactok.mli | 2 ++ src/dune | 1 + src/plibrary.ml4 | 7 ++++++- 14 files changed, 64 insertions(+), 38 deletions(-) delete mode 100644 coq/FundamentalArithmetics.v delete mode 100644 coq/Test.v delete mode 160000 deps/fundamental-arithmetics delete mode 160000 fundamental-arithmetics create mode 100644 src/coq/tactok/coq_gym.yml create mode 100644 src/coq/tactok/dune diff --git a/.gitmodules b/.gitmodules index 0f6970d..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "deps/fundamental-arithmetics"] - path = deps/fundamental-arithmetics - url = https://github.com/coq-contribs/fundamental-arithmetics diff --git a/coq/FundamentalArithmetics.v b/coq/FundamentalArithmetics.v deleted file mode 100644 index a3a30c3..0000000 --- a/coq/FundamentalArithmetics.v +++ /dev/null @@ -1,16 +0,0 @@ -Add LoadPath "./deps/fundamental-arithmetics" as FundamentalArithmetics. -From FundamentalArithmetics Require Import - division euclide gcd missing nthroot permutation - power primes. -Require Import Patcher.Patch. - - -Decompile Module division. -Decompile Module euclide. -Decompile Module gcd. -Decompile Module missing. -Decompile Module nthroot. -Decompile Module permutation. -Decompile Module power. -Decompile Module primes. - diff --git a/coq/Test.v b/coq/Test.v deleted file mode 100644 index 7d158d9..0000000 --- a/coq/Test.v +++ /dev/null @@ -1 +0,0 @@ -Require Import CoqPluginLib.Plib. diff --git a/deps/fundamental-arithmetics b/deps/fundamental-arithmetics deleted file mode 160000 index 8976d4b..0000000 --- a/deps/fundamental-arithmetics +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8976d4ba6a5c53b7eb25d08921e592d200189431 diff --git a/fundamental-arithmetics b/fundamental-arithmetics deleted file mode 160000 index 8976d4b..0000000 --- a/fundamental-arithmetics +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8976d4ba6a5c53b7eb25d08921e592d200189431 diff --git a/src/coq/decompiler/decompiler.ml b/src/coq/decompiler/decompiler.ml index 9e26d57..1994b0a 100644 --- a/src/coq/decompiler/decompiler.ml +++ b/src/coq/decompiler/decompiler.ml @@ -15,6 +15,8 @@ open Zooming open Nameutils open Ltac_plugin open Stateutils +open List +open Tactok (* * This is a minimal, sound version of the decompiler with our own heuristics @@ -227,6 +229,9 @@ let apply_implicit env sigma trm : tactical state option = qed sigma tac with _ -> None +let get_hints env sigma prev goal = + sigma, (beam_search env (List.rev prev) goal) + (* Performs the bulk of decompilation on a proof term. Opts are the optional goal solving tactics that can be inserted into the generated script. If one of these tactics solves the focused goal or @@ -300,8 +305,8 @@ and many_subgoals env sigma opts prev goal t trms = and try_custom_tacs env sigma get_hints prev goal trm : tactical state option = guard (not (isLambda trm)) >>= fun _ -> try - let sigma, hints = get_hints env sigma prev trm in let goal = (Typeops.infer env trm).uj_type in + let sigma, hints = get_hints env sigma prev goal in let rec aux opts : tactical state option = match opts with | [] -> None @@ -464,7 +469,7 @@ and apply_in (n, valu, _, body) (env, sigma, opts, prev, goal) : tactical state in (apply_binding <|> default) () (env', sigma) -(* Last resort decompile let-in as a pose. *) +(* Last resort decompile let-in as a pose. *) and pose (n, valu, typ, body) (env, sigma, opts, prev, goal) : tactical state option = let n' = fresh_name env n in let env' = push_let_in (Name n', valu, typ) env in @@ -482,7 +487,7 @@ and pose (n, valu, typ, body) (env, sigma, opts, prev, goal) : tactical state op let tac_from_term env sigma get_hints trm : tactical state = let sigma, goal = Inference.infer_type env sigma trm in first_pass env sigma get_hints [] goal trm - + (* Generate indentation space before bullet. *) let indent level = let spacing level = (level - 2) / 3 + 2 in @@ -508,7 +513,7 @@ let pp_concat sep xs = | x :: [] -> [ x ] | x :: xs' -> x :: sep :: aux xs' in seq (aux xs) - + (* Show tactical, composed of many tactics. *) let rec show_tactical sigma (level : int) (bulletted : bool) (t : tactical) : Pp.t = let full_indent = if bulletted @@ -522,7 +527,6 @@ let rec show_tactical sigma (level : int) (bulletted : bool) (t : tactical) : Pp tac_s ++ match goals with | [ goal ] -> show_tactical sigma level false goal | goals -> seq (List.mapi f goals) - + (* Represent tactics as a string. *) -let tac_to_string sigma = show_tactical sigma 0 false - +let tac_to_string sigma = show_tactical sigma 0 false \ No newline at end of file diff --git a/src/coq/dune b/src/coq/dune index fa885ff..567bfbb 100644 --- a/src/coq/dune +++ b/src/coq/dune @@ -16,5 +16,6 @@ coq-plugin-lib.inductive coq-plugin-lib.representationutils coq-plugin-lib.termutils + coq-plugin-lib.tactok coq.kernel) (wrapped false)) diff --git a/src/coq/tactok/agent_utils.py b/src/coq/tactok/agent_utils.py index a1d4275..8086cb7 100644 --- a/src/coq/tactok/agent_utils.py +++ b/src/coq/tactok/agent_utils.py @@ -5,9 +5,10 @@ import string term_parser = GallinaTermParser(caching=True) -sexp_cache = SexpCache('../sexp_cache', readonly=True) #include this +sexp_cache = SexpCache('../../../../sexp_cache', readonly=True) # include this outside top directory def get_opts(): + # TODO: need to update opts as we go parser = argparse.ArgumentParser() parser.add_argument('--path', type=str, default='model.pth') parser.add_argument('--beam_width', type=int, default=10) diff --git a/src/coq/tactok/coq_gym.yml b/src/coq/tactok/coq_gym.yml new file mode 100644 index 0000000..c5cc59d --- /dev/null +++ b/src/coq/tactok/coq_gym.yml @@ -0,0 +1,16 @@ +name: coq_gym +channels: + - defaults +dependencies: + - numpy=1.16.2 + - numpy-base=1.16.2 + - python=3.7.1 + - pip=19.0.3 + - pip: + - lark-parser==0.6.5 + - lmdb==0.94 + - pandas==0.24.2 + - pexpect==4.6.0 + - progressbar2==3.39.3 + - sexpdata==0.0.3 + - torch \ No newline at end of file diff --git a/src/coq/tactok/dune b/src/coq/tactok/dune new file mode 100644 index 0000000..90c6d67 --- /dev/null +++ b/src/coq/tactok/dune @@ -0,0 +1,16 @@ +(library + (name tactok) + (public_name coq-plugin-lib.tactok) + (libraries + coq-serapi.serlib + lymp + coq-plugin-lib.hofimpls + coq-plugin-lib.devutils + coq-plugin-lib.constants + coq-plugin-lib.inductive + coq-plugin-lib.contexts + coq-plugin-lib.decompiler + coq.engine + coq.kernel + coq.plugins.ltac) + (wrapped false)) \ No newline at end of file diff --git a/src/coq/tactok/tactok.ml b/src/coq/tactok/tactok.ml index 5f80be7..f1cdf97 100644 --- a/src/coq/tactok/tactok.ml +++ b/src/coq/tactok/tactok.ml @@ -16,10 +16,12 @@ open Ltac_plugin open Stateutils open Lymp open Ser_names +open Ser_environ +open Ser_goal let py = init "." -let agent_utils = get_module py "agent_utils" -let prover = get_module py "prover" +let agent_utils = Lymp.get_module py "agent_utils" +let prover = Lymp.get_module py "prover" (* Follow this format *) (* let module = Lymp.get_module py in @@ -36,8 +38,8 @@ let beam_search env prev goal = let model = import_model () in let script = parse_script prev in (* need to reverse prev *) (* ser api calls to serialize *) - let ser_env = pp_format env in - let ser_goal = pp_format goal in - let filter_env = get_ref agent_utils "filter_env" [Pyref ser_env] in - let local_context, parsed_goal = get_ref agent_utils "parse_goal" [Pyref ser_goal] in - get_list prover "beam_search" [Pyref model; Pyref filter_env; Pyref local_context; Pyref parsed_goal; Pylist script] in \ No newline at end of file + let ser_env = sexp_of_env env in + let ser_goal = sexp_of_goal goal in + let filter_env = Lymp.get_ref agent_utils "filter_env" [Pyref ser_env] in + let local_context, parsed_goal = Lymp.get_ref agent_utils "parse_goal" [Pyref ser_goal] in + get_list prover "beam_search" [Pyref model; Pyref filter_env; Pyref local_context; Pyref parsed_goal; Pylist script] diff --git a/src/coq/tactok/tactok.mli b/src/coq/tactok/tactok.mli index f2b274f..cf23a4c 100644 --- a/src/coq/tactok/tactok.mli +++ b/src/coq/tactok/tactok.mli @@ -16,5 +16,7 @@ open Ltac_plugin open Stateutils open Lymp open Ser_names +open Ser_environ +open Ser_goal val beam_search : env -> string list -> types -> string list diff --git a/src/dune b/src/dune index efd6d4b..6eb1bfa 100644 --- a/src/dune +++ b/src/dune @@ -13,6 +13,7 @@ coq-plugin-lib.coq coq-plugin-lib.debruijn coq-plugin-lib.constants + coq-plugin-lib.tactok coq-plugin-lib.decompiler coq-plugin-lib.devutils coq-plugin-lib.envs diff --git a/src/plibrary.ml4 b/src/plibrary.ml4 index 4254523..311e696 100644 --- a/src/plibrary.ml4 +++ b/src/plibrary.ml4 @@ -28,6 +28,9 @@ open Tacarg open List open Ser_names +open Ser_environ +open Ser_goal +open Ser_constr open Lymp (* --- Commands --- *) @@ -39,7 +42,9 @@ let decompile_command trm tacs = let trm = unwrap_definition env trm in let opts = map (fun s -> (parse_tac_str s, s)) tacs in let sigma, script = tac_from_term env sigma (fun _ sigma [] _ -> sigma, opts) trm in - (* let sigma, goal = infer_type env sigma trm in *) + (* let ser_env = sexp_of_env env in *) + (* let goal = (Typeops.infer env trm).uj_type in *) + (* let ser_goal = sexp_of_constr goal in *) (* Feedback.msg_warning (ppx_conv_sexp env sigma goal) *) (* Feedback.msg_warning (str "the goal: " ++ Printer.pr_constr_env env sigma goal) *) (* Feedback.msg_debug (script) *)