Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work on inference, unification and subject-reduction #328

Merged
merged 71 commits into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
f2bd761
fix #303 handling of metavariables in RHS
fblanqui Apr 2, 2020
8f068a0
fix typo in comment
fblanqui Apr 2, 2020
a8b9916
fix typo in comment
fblanqui Apr 2, 2020
50069df
prepare fix
fblanqui Apr 2, 2020
17a6a50
fix typos in comments
fblanqui Apr 2, 2020
465215c
fix typo in comment
fblanqui Apr 2, 2020
9865cc8
fix typo in comment
fblanqui Apr 2, 2020
ce199bc
indentation
fblanqui Apr 2, 2020
d82b019
comment optim: reserve space for all LHS variables and not only those…
fblanqui Apr 3, 2020
db583e2
remove subst_from_constrs as it is useless
fblanqui Apr 3, 2020
e91ee90
basics: add fresh_vars
fblanqui Apr 3, 2020
588eddc
infer: change in log message
fblanqui Apr 3, 2020
d369293
Terms.set_meta: do not erase the type!
fblanqui Apr 3, 2020
2706e78
unif: log instantiations
fblanqui Apr 3, 2020
212e1cc
scope: replace wildcard pattern variables by fresh named pattern vari…
fblanqui Apr 3, 2020
7790644
fix sr by replacing LHS metas by fresh function symbols before solvin…
fblanqui Apr 3, 2020
b2b7d03
details in tests
fblanqui Apr 3, 2020
28e84a0
new test
fblanqui Apr 3, 2020
05996f8
infer: change in log message
fblanqui Apr 3, 2020
0b8037a
add basics.add_metas
fblanqui Apr 3, 2020
e7b7bc7
sr: details
fblanqui Apr 3, 2020
e285838
terms: add MetaMap
fblanqui Apr 3, 2020
e0d283d
improve sr
fblanqui Apr 3, 2020
05710a7
Merge remote-tracking branch 'lp/master' into rhs_metas
fblanqui Apr 4, 2020
c051cef
change some log message
fblanqui Apr 4, 2020
542660b
unif: improvement
fblanqui Apr 4, 2020
f798b2a
handle first example of #330
fblanqui Apr 4, 2020
27ceb83
fix bug in infer
fblanqui Apr 5, 2020
5a3040c
fix second problem in #330
fblanqui Apr 5, 2020
a94a34b
remove old comment
fblanqui Apr 5, 2020
95057aa
sanity
fblanqui Apr 5, 2020
d5dd1ee
remove lib directory
fblanqui Apr 6, 2020
105d47d
move eq from basics to rewrite
fblanqui Apr 6, 2020
036b8b5
infer: use eq_modulo in conv + more log messages
fblanqui Apr 6, 2020
f440308
scope: fix some comments
fblanqui Apr 6, 2020
4aa951e
remove Solve.can_instantiate and Terms.internal
fblanqui Apr 6, 2020
f86ad7b
improvement in sr
fblanqui Apr 6, 2020
f727612
remove warnings
fblanqui Apr 6, 2020
fccfd7c
update comment
fblanqui Apr 6, 2020
b0e1bb9
Terms.set_meta: erase type again for saving memory usage
fblanqui Apr 6, 2020
d1e0561
test 330 does not pass anymore
fblanqui Apr 6, 2020
cd798e5
rewrite: use eq_modulo for checking builtins
fblanqui Apr 6, 2020
759131a
changes in log messages
fblanqui Apr 6, 2020
6245738
details
fblanqui Apr 6, 2020
d1f39eb
details
fblanqui Apr 6, 2020
91a1452
details
fblanqui Apr 6, 2020
f76704b
why3_tactic: replace Rewrite.eq by Eval.eq_modulo
fblanqui Apr 7, 2020
935bff8
Makefile: add lib root for tests
fblanqui Apr 7, 2020
a5c3611
Merge remote-tracking branch 'lp/master' into rhs_metas
fblanqui Apr 7, 2020
abe7462
Makefile: change lib root to /tmp
fblanqui Apr 7, 2020
a188591
sr: remove useless comments + replace ? by & in function symbol names
fblanqui Apr 7, 2020
ee234b9
unif: improve nl_distinct_vars and instantiation to take into account…
fblanqui Apr 7, 2020
9c9ce7c
Unif.instantiation optim: do not apply sym_to_var if m is empty
fblanqui Apr 7, 2020
f1a94f1
change log message
fblanqui Apr 9, 2020
6b532da
fix remarks by Gabriel
fblanqui Apr 9, 2020
445be54
Merge remote-tracking branch 'lp/master' into rhs_metas
fblanqui Apr 9, 2020
f6a3405
comments by Rodolphe
fblanqui Apr 9, 2020
057d6a0
comment by Gabriel
fblanqui Apr 9, 2020
2d7742b
put back lib directory
fblanqui Apr 9, 2020
8277830
remark by Rodolphe
fblanqui Apr 9, 2020
17c2d41
add tests/OK/328.lp
fblanqui Apr 9, 2020
264dd66
sr: simplification of to_m (type extension is taken care by unificati…
fblanqui Apr 9, 2020
81557c2
Merge remote-tracking branch 'lp/master' into rhs_metas
fblanqui Apr 10, 2020
e5dd8a6
Merge remote-tracking branch 'lp/master' into rhs_metas
fblanqui Apr 10, 2020
8a784d1
Cleaning up SR and scoping of rules.
rlepigre Apr 9, 2020
2af80c3
Apply a comment I forgot.
rlepigre Apr 10, 2020
5eb7eda
Typo.
rlepigre Apr 10, 2020
07a3f39
Apply my own comments.
rlepigre Apr 10, 2020
d367273
Add missing comment.
rlepigre Apr 10, 2020
0cc857f
Apply my own comment again.
rlepigre Apr 10, 2020
a0e1f3e
Added comment.
rlepigre Apr 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/core/basics.ml
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,13 @@ let occurs : meta -> term -> bool =
let fn p = if m == p then raise Found in
try iter_meta false fn t; false with Found -> true

(** [get_metas b t] returns the list of all the metavariables in [t], and in
the types of metavariables recursively if [b], sorted wrt [cmp_meta]. *)
let get_metas : bool -> term -> meta list = fun b t ->
(** [get_metas b t] returns the set of all the metavariables in [t], and in
the types of metavariables recursively if [b]. *)
let get_metas : bool -> term -> MetaSet.t = fun b t ->
let open Stdlib in
let l = ref [] in
iter_meta b (fun m -> l := m :: !l) t;
List.sort_uniq cmp_meta !l
fblanqui marked this conversation as resolved.
Show resolved Hide resolved
let ms = ref MetaSet.empty in
iter_meta b (fun m -> ms := MetaSet.add m !ms) t;
!ms

(** [has_metas b t] checks whether there are metavariables in [t], and in the
types of metavariables recursively if [b] is true. *)
Expand Down Expand Up @@ -246,4 +246,4 @@ let term_of_rhs : rule -> term = fun r ->
let p = _Patt (Some(i)) name (Array.map Bindlib.box_var vars) in
TE_Some(Bindlib.unbox (Bindlib.bind_mvar vars p))
in
Bindlib.msubst r.rhs (Array.mapi fn r.vars)
Bindlib.msubst r.rhs (Array.mapi fn r.pvs)
9 changes: 9 additions & 0 deletions src/core/extra.ml
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,15 @@ module List =
| _ -> false
in in_sorted

(** [insert cmp x l] inserts [x] in the list [l] assuming that [l] is
sorted wrt [cmp]. *)
let insert : 'a cmp -> 'a -> 'a list -> 'a list = fun cmp x ->
let rec insert acc l =
match l with
| y :: m when cmp x y > 0 -> insert (y::acc) m
| _ -> List.rev_append acc (x::l)
in insert []

rlepigre marked this conversation as resolved.
Show resolved Hide resolved
end

module Array =
Expand Down
6 changes: 6 additions & 0 deletions src/core/proof.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ module Goal :

(** [simpl g] simplifies the given goal, evaluating its type to SNF. *)
val simpl : t -> t

(** Comparison function. *)
val compare : t -> t -> int
fblanqui marked this conversation as resolved.
Show resolved Hide resolved
end =
struct
type t =
Expand All @@ -42,6 +45,9 @@ module Goal :

let simpl : t -> t = fun g ->
{g with goal_type = Eval.snf (Env.to_ctxt g.goal_hyps) g.goal_type}

let compare : t -> t -> int = fun g1 g2 ->
Meta.compare g1.goal_meta g2.goal_meta
end

(** Representation of the proof state of a theorem. *)
Expand Down
27 changes: 14 additions & 13 deletions src/core/scope.ml
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,14 @@ let scope : mode -> sig_state -> env -> p_term -> tbox = fun md ss env t ->
| (P_Wild , M_LHS(_) ) -> fresh_patt env
| (P_Wild , M_Patt ) -> _Wild
| (P_Wild , _ ) ->
(* We create a metavariable [m] of type [m_ty], which is itself also a
metavariable (of type [Type]). Note that this case applies both to
regular terms, and to the RHS of rewriting rules. *)
(* We create a metavariable [m] of type [tm], which itself is also a
metavariable [x] of type [Type]. Note that this case applies both
to regular terms, and to the RHS of rewriting rules. *)
let vs = Env.to_tbox env in
let m_ty = fresh_meta (Env.to_prod env _Type) (Array.length vs) in
let a = Env.to_prod env (_Meta m_ty vs) in
let m = fresh_meta a (Array.length vs) in
let n = Array.length vs in
let x = fresh_meta (Env.to_prod env _Type) n in
let tm = Env.to_prod env (_Meta x vs) in
let m = fresh_meta tm n in
_Meta m vs
| (P_Meta(id,ts) , M_Term(m,_) ) ->
let m2 =
Expand Down Expand Up @@ -480,7 +481,7 @@ let scope_rule : sig_state -> p_rule -> sym * pp_hint * rule loc = fun ss r ->
let (pvs_lhs, nl) = patt_vars p_lhs in
let (pvs_rhs, _ ) = patt_vars p_rhs in
(* NOTE to reject non-left-linear rules, we can check [nl = []] here. *)
(* Check that the meta-variables of the RHS exist in the LHS. *)
(* Check that the pattern variables of the RHS exist in the LHS. *)
let check_in_lhs (m,i) =
let j =
try List.assoc m pvs_lhs with Not_found ->
Expand All @@ -491,11 +492,11 @@ let scope_rule : sig_state -> p_rule -> sym * pp_hint * rule loc = fun ss r ->
List.iter check_in_lhs pvs_rhs;
(* Get the non-linear variables not in the RHS. *)
let nl = List.filter (fun m -> not (List.mem_assoc m pvs_rhs)) nl in
(* Reserve space for meta-variables that appear non-linearly in the LHS. *)
(* Reserve space for pattern variables that appear non-linearly in the LHS. *)
let pvs = List.map (fun m -> (m, List.assoc m pvs_lhs)) nl @ pvs_rhs in
let map = List.mapi (fun i (m,_) -> (m,i)) pvs in
(* NOTE [map] maps meta-variables to their position in the environment. *)
(* NOTE meta-variables not in [map] can be considered as wildcards. *)
(* NOTE [map] maps pattern variables to their position in the environment. *)
(* NOTE pattern variables not in [map] can be considered as wildcards. *)
(* Get privacy of the head of the rule, and scope the rest with this
privacy. *)
let prv = is_private (fst (get_root p_lhs ss)) in
Expand All @@ -515,7 +516,7 @@ let scope_rule : sig_state -> p_rule -> sym * pp_hint * rule loc = fun ss r ->
fatal p_lhs.pos "No head symbol in LHS."
in
if lhs = [] then wrn p_lhs.pos "LHS head symbol with no argument.";
(* We scope the RHS and bind the meta-variables. *)
(* We scope the RHS and bind the pattern variables. *)
let names = Array.of_list (List.map fst map) in
let vars = Bindlib.new_mvar te_mkfree names in
let rhs =
Expand All @@ -524,9 +525,9 @@ let scope_rule : sig_state -> p_rule -> sym * pp_hint * rule loc = fun ss r ->
Bindlib.unbox (Bindlib.bind_mvar vars (scope mode ss Env.empty p_rhs))
in
(* We also store [pvs] to facilitate confluence / termination checking. *)
let vars = Array.of_list pvs in
let pvs = Array.of_list pvs in
(* We put everything together to build the rule. *)
(sym, hint, Pos.make r.pos {lhs; rhs; arity = List.length lhs; vars})
(sym, hint, Pos.make r.pos {lhs; rhs; arity = List.length lhs; pvs; vars})

(** [scope_pattern ss env t] turns a parser-level term [t] into an actual term
that will correspond to selection pattern (rewrite tactic). *)
Expand Down
20 changes: 15 additions & 5 deletions src/core/sr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ let build_meta_type : int -> term = fun k ->
let check_rule : sym StrMap.t -> sym * pp_hint * rule Pos.loc -> unit =
fun builtins (s,h,r) ->
if !log_enabled then log_subj "check_rule [%a]" pp_rule (s, h, r.elt);
(* We process the LHS to replace pattern variables by metavariables. *)
let binder_arity = Bindlib.mbinder_arity r.elt.rhs in
(* Compute the metavariables of the RHS. *)
let rhs = Bindlib.msubst r.elt.rhs (Array.make binder_arity TE_None) in
let rhs_metas = Basics.get_metas true rhs in
(* We process the LHS to replace pattern variables by metavariables. *)
let metas = Array.make binder_arity None in
let rec to_m : int -> term -> tbox = fun k t ->
(* [k] is the number of arguments to which [m] is applied. *)
Expand Down Expand Up @@ -102,8 +105,8 @@ let check_rule : sym StrMap.t -> sym * pp_hint * rule Pos.loc -> unit =
| Wild -> assert false (* Cannot appear in LHS. *)
| TRef(_) -> assert false (* Cannot appear in LHS. *)
in
let lhs = List.map (fun p -> Bindlib.unbox (to_m 0 p)) r.elt.lhs in
let lhs = Basics.add_args (Symb(s,h)) lhs in
let lhs_args = List.map (fun p -> Bindlib.unbox (to_m 0 p)) r.elt.lhs in
let lhs = Basics.add_args (Symb(s,h)) lhs_args in
let metas = Array.map (function Some m -> m | None -> assert false) metas in
(* We substitute the RHS with the corresponding metavariables. *)
let fn m =
Expand All @@ -113,7 +116,14 @@ let check_rule : sym StrMap.t -> sym * pp_hint * rule Pos.loc -> unit =
TE_Some(Bindlib.unbox (Bindlib.bind_mvar xs (_Meta m e)))
in
let te_envs = Array.map fn metas in
let rhs = Bindlib.msubst r.elt.rhs te_envs in
let subst t = Bindlib.msubst t te_envs in
let rhs = subst r.elt.rhs in
(* We substitute the metavariables of the RHS as well. *)
let fn m =
let bt = lift !(m.meta_type) in
m.meta_type := subst (Bindlib.unbox (Bindlib.bind_mvar r.elt.vars bt))
in
MetaSet.iter fn rhs_metas;
(* Infer the type of the LHS and the constraints. *)
match Typing.infer_constr builtins [] lhs with
| None -> wrn r.pos "Untypable LHS."
Expand Down Expand Up @@ -160,7 +170,7 @@ let check_rule : sym StrMap.t -> sym * pp_hint * rule Pos.loc -> unit =
(* Check that there is no uninstanciated metas left. *)
let lhs_metas = Basics.get_metas false lhs in
let f m =
if not (List.in_sorted cmp_meta m lhs_metas) then
if not (MetaSet.mem m lhs_metas) then
fatal r.pos "Cannot instantiate all metavariables in rule [%a]."
pp_rule (s,h,r.elt)
in
Expand Down
5 changes: 4 additions & 1 deletion src/core/tactics.ml
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,12 @@ let handle_tactic : sig_state -> Proof.t -> p_tactic -> Proof.t =
set_meta m (Bindlib.unbox (Bindlib.bind_mvar (Env.vars env) (lift t)));
(* New subgoals and focus. *)
let metas = Basics.get_metas true t in
let new_goals = List.map Proof.Goal.of_meta metas in
let add_goal m = List.insert Proof.Goal.compare (Proof.Goal.of_meta m) in
let new_goals = MetaSet.fold add_goal metas [] in
(* New goals must appear first. *)
Proof.({ps with proof_goals = new_goals @ gs})
in

fblanqui marked this conversation as resolved.
Show resolved Hide resolved
match tac.elt with
| P_tac_print
| P_tac_proofterm
Expand Down
15 changes: 9 additions & 6 deletions src/core/terms.ml
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,10 @@ type term =
(** Right hand side (or RHS). *)
; arity : int
(** Required number of arguments to be applicable. *)
; vars : (string * int) array
(** Name and arity of the pattern variables bound in the RHS. *) }
; pvs : (string * int) array
(** Name and arity of the pattern variables bound in the RHS. *)
fblanqui marked this conversation as resolved.
Show resolved Hide resolved
; vars : term_env Bindlib.var array
(** Bindlib variables used to build [rhs]. *) }

(** The LHS (or pattern) of a rewriting rule is always formed of a head symbol
(on which the rule is defined) applied to a list of pattern arguments. The
Expand Down Expand Up @@ -242,11 +244,12 @@ type term =
; meta_value : (term, term) Bindlib.mbinder option ref
(** Definition of the metavariable, if known. *) }

(** Comparison function on metavariables. *)
let cmp_meta : meta -> meta -> int = fun m1 m2 -> m1.meta_key - m2.meta_key
module Meta = struct
type t = meta
let compare m1 m2 = m1.meta_key - m2.meta_key
end

(** Equality on metavariables. *)
let eq_meta : meta -> meta -> bool = fun m1 m2 -> m1.meta_key = m2.meta_key
fblanqui marked this conversation as resolved.
Show resolved Hide resolved
module MetaSet = Set.Make(Meta)

(** [symb s] returns the term [Symb (s, Nothing)]. *)
let symb : sym -> term = fun s -> Symb (s, Nothing)
Expand Down
2 changes: 1 addition & 1 deletion src/core/xtc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ let print_tl_rule : Format.formatter -> int -> sym -> rule -> unit =
in the form of a pair containing the name of the variable and its type,
inferred by the solver. *)
let get_vars : sym -> rule -> (string * Terms.term) list = fun s r ->
let rule_ctx : tvar option array = Array.make (Array.length r.vars) None in
let rule_ctx : tvar option array = Array.make (Array.length r.pvs) None in
let var_list : tvar list ref = ref [] in
let rec subst_patt v t =
match t with
Expand Down
11 changes: 11 additions & 0 deletions tests/OK/303.lp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
constant symbol U : TYPE

constant symbol u : U

constant symbol f : (U ⇒ U) ⇒ TYPE

symbol G : U ⇒ TYPE

constant symbol H : U ⇒ TYPE

rule G &v → ∀ (a : H &v), f (λ _, u)
2 changes: 1 addition & 1 deletion tests/OK/logic.lp
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,4 @@ set builtin "top" ≔ top
set builtin "imp" ≔ imp
set builtin "and" ≔ {|and|}
set builtin "or" ≔ or
set builtin "not" ≔ not
set builtin "not" ≔ not