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

Extending the type preservation check #189

Merged
merged 41 commits into from
Feb 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
6e1cc85
Extending elaboration of a substitution from constraints
Aug 1, 2019
314d364
Extend pseudo unification, to pseudo-unify (x => A) and (x => B x)
Aug 1, 2019
21526db
Merge branch 'master' into cstr-recording
Dec 3, 2019
bc78af4
Moved back to master.
Dec 6, 2019
ae679b3
Merge branch 'master' into cstr-recording
Dec 6, 2019
79e04f8
Added challenging tests.
Dec 6, 2019
6d07b00
Moved tests from type-preserv PR.
Dec 6, 2019
313c7c3
First implementation passing first order test.
Dec 6, 2019
fa40d81
Extended substitution.
Dec 6, 2019
61ee700
Used extended substitutions.
Dec 6, 2019
3f03e09
Started using exsubst in typing. Some bugs.
Dec 6, 2019
9262f1e
Fixed criteria and tests.
Dec 10, 2019
0af6a6c
Added FIXME comment.
Dec 10, 2019
ce4791e
Indentation
GuillaumeGen Dec 10, 2019
d72f2f1
A naive use of the unsolved constraints
GuillaumeGen Dec 10, 2019
987e3f0
Due to my very bad practice, the previous commit of Gaspard was lost
GuillaumeGen Dec 10, 2019
6d86c2f
Update typing.ml
GuillaumeGen Dec 10, 2019
540279f
Made cstr_comparison global.
Dec 11, 2019
d40110b
Added tests and fixed bis function.
Dec 11, 2019
e4b6517
Added some tests.
Dec 11, 2019
b13bc2b
Fixed buggy test. Implemented conversion under exsubst.
Dec 11, 2019
4f2db0e
Fixed extended substitution application.
Dec 11, 2019
51cc005
Merge branch 'master' into cstr-recording
Dec 11, 2019
39fb143
Added comments and removed unused Subst module.
Dec 13, 2019
0b70155
Some style. Fixed a test. Made convertible_under_cstr tail rec.
Dec 13, 2019
7450167
Experimentations.
Dec 13, 2019
b1de1b5
WIP
Dec 13, 2019
377ce08
Moved SR checking to a separate module.
Dec 16, 2019
22fb8a8
Moved SR checking to a separate module.
Dec 16, 2019
0635cdc
Fixed implementation.
Dec 16, 2019
dc45521
Added missing comment in test.
Dec 16, 2019
d33ed1a
Added unit testing.
Dec 17, 2019
0f55eca
Added SR checking debug messages.
Dec 17, 2019
a95f05a
Rule-loggin LHS constraint substitution
Dec 17, 2019
8ab2bb9
Do not compute snf if no constraint remains
Dec 17, 2019
f9aa580
Merge branch 'cstr-recording' into cstr-rec2
Dec 18, 2019
3dc8024
Fixed evaluation order bug.
Dec 18, 2019
b94ba13
A few cleaning to improve readibility
GuillaumeGen Feb 14, 2020
8bada49
Merge pull request #211 from Deducteam/cstr-rec2
GuillaumeGen Feb 14, 2020
c4c0b27
Merge of master
GuillaumeGen Feb 14, 2020
5cf3351
Doc
GuillaumeGen Feb 14, 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
5 changes: 3 additions & 2 deletions api/env.ml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let set_debug_mode =
| 'c' -> Debug.enable_flag Confluence.d_confluence
| 'u' -> Debug.enable_flag Typing.d_rule
| 't' -> Debug.enable_flag Typing.d_typeChecking
| 's' -> Debug.enable_flag Srcheck.d_SR
| 'r' -> Debug.enable_flag Reduction.d_reduce
| 'm' -> Debug.enable_flag Matching.d_matching
| c -> raise (DebugFlagNotRecognized c)
Expand Down Expand Up @@ -65,7 +66,7 @@ sig
val define : loc -> ident -> Signature.scope ->
bool -> term -> term option -> unit
val add_rules : Rule.partially_typed_rule list ->
(Subst.Subst.t * Rule.typed_rule) list
(Exsubst.ExSubst.t * Rule.typed_rule) list

val infer : ?ctx:typed_context -> term -> term
val check : ?ctx:typed_context -> term -> term -> unit
Expand Down Expand Up @@ -193,7 +194,7 @@ struct
try _define lc id scope op te ty_opt
with e -> raise_as_env lc e

let add_rules (rules: partially_typed_rule list) : (Subst.Subst.t * typed_rule) list =
let add_rules (rules: partially_typed_rule list) : (Exsubst.ExSubst.t * typed_rule) list =
try
let rs2 = List.map (T.check_rule !sg) rules in
_add_rules rules;
Expand Down
2 changes: 1 addition & 1 deletion api/env.mli
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ sig
val define : loc -> ident -> Signature.scope -> bool -> term -> term option -> unit
(** [define l id scope body ty] defines the symbol [id] of type [ty] to be an alias of [body]. *)

val add_rules : Rule.partially_typed_rule list -> (Subst.Subst.t * Rule.typed_rule) list
val add_rules : Rule.partially_typed_rule list -> (Exsubst.ExSubst.t * Rule.typed_rule) list
(** [add_rules rule_lst] adds a list of rule to a symbol. All rules must be on the
same symbol. *)

Expand Down
2 changes: 1 addition & 1 deletion api/processor.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct
let rs = E.add_rules rs in
List.iter (fun (s,r) ->
Debug.debug Debug.d_notice "%[email protected] the following constraints: %a"
pp_typed_rule r (Subst.Subst.pp (fun n -> let _,n,_ = List.nth r.ctx n in n)) s) rs
pp_typed_rule r (Exsubst.ExSubst.pp (fun n -> let _,n,_ = List.nth r.ctx n in n)) s) rs
| Eval(_,red,te) ->
let te = E.reduction ~red te in
Format.printf "%a@." Printer.print_term te
Expand Down
8 changes: 7 additions & 1 deletion commands/dkcheck.ml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ let _ =
c : (confluence) notifies about information provided to the confluence
checker (when option --confluence used)
u : (rule) provides information about type checking of rules
t : (typing) provides information about type-checking of terms
t : (typing) provides information about type checking of terms
s : (SR) provides information about subject reduction checking of terms
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SR criterion here is for the rules, not terms in general, right?

r : (reduce) provides information about reduction performed in terms
m : (matching) provides information about pattern matching" )
; ( "-v"
Expand Down Expand Up @@ -92,6 +93,11 @@ let _ =
; ( "--type-lhs"
, Arg.Set Typing.fail_on_unsatisfiable_constraints
, " Forbids rules with untypable left-hand side" )
; ( "--sr-check"
, Arg.Int (fun i -> Srcheck.srfuel := i)
, "LVL Sets the level of subject reduction checking to LVL.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LVL Sets... it should be --sr-check right?

Default value is 1. Values < 0 may not terminate on
rules that do not preserve typing. " )
; ( "--snf"
, Arg.Set Errors.errors_in_snf
, " Normalizes all terms printed in error messages" )
Expand Down
119 changes: 119 additions & 0 deletions kernel/exsubst.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
open Basic
open Format
open Term

(** An extended substitution is a function mapping
- a variable (location, identifier and DB index)
- applied to a given number of arguments
- under a given number of lambda abstractions
to a term.
A substitution raises Not_found meaning that the variable is not subsituted. *)
type ex_substitution = loc -> ident -> int -> int -> int -> term

(** [apply_exsubst subst n t] applies [subst] to [t] under [n] lambda abstractions.
- Variables with DB index [k] < [n] are considered "locally bound" and are never substituted.
- Variables with DB index [k] >= [n] may be substituted if [k-n] is mapped in [sigma]
and if they occur applied to enough arguments (substitution's arity). *)
let apply_exsubst (subst:ex_substitution) (n:int) (te:term) : term*bool =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this function cannot be implemented by one of the subst function? Why this function is not in the module Subst?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I rephrase, why do we have two modules for substitution now? Why don't we keep only one module for substitutions?

let ct = ref 0 in
(* aux increments this counter every time a substitution occurs.
* Terms are reused when no substitution occurs in recursive calls. *)
let rec aux k t = match t with (* k counts the number of local lambda abstractions *)
| DB (l,x,n) when n >= k -> (* a free variable *)
( try let res = subst l x n 0 k in incr ct; res with Not_found -> t)
| App (DB (l,x,n) as db,a,args) when n >= k -> (* an applied free variable *)
let ct' = !ct in
let f' =
try
let res = subst l x n (1+(List.length args)) k in
incr ct;
res
with Not_found -> db in
let a', args' = aux k a, List.map (aux k) args in
if !ct = ct' then t else mk_App f' a' args'
| App (f,a,args) ->
let ct' = !ct in
let f', a', args' = aux k f, aux k a, List.map (aux k) args in
if !ct = ct' then t else mk_App f' a' args'
| Lam (l,x,a,f) ->
let ct' = !ct in
let a', f' = map_opt (aux k) a, aux (k+1) f in
if !ct = ct' then t else mk_Lam l x a' f'
| Pi (l,x,a,b) ->
let ct' = !ct in
let a', b' = aux k a, aux (k+1) b in
if !ct = ct' then t else mk_Pi l x a' b'
| _ -> t
in let res = aux n te in (res, !ct > 0)

module IntMap = Map.Make(
struct
type t = int
let compare = compare
end)

module ExSubst =
struct
type t = (int*term) IntMap.t
(* Maps a DB index to an arity and a lambda-lifted substitute *)
let identity = IntMap.empty
let is_identity = IntMap.is_empty

(** Substitution function corresponding to given ExSubst.t instance [sigma].
We lookup the table at index: (DB index) [n] - (nb of local binders) [k]
When the variable is under applied it is simply not substituted.
Otherwise we return the reduct is shifted up by (nb of local binders) [k] *)
let subst (sigma:t) =
fun _ _ n nargs k ->
let (arity,t) = IntMap.find (n-k) sigma in
if nargs >= arity then Subst.shift k t else raise Not_found

(** Special substitution function corresponding to given ExSubst.t instance [sigma]
"in a smaller context":
Assume [sigma] a substitution in a context Gamma = Gamma' ; Delta with |Delta|=[i].
Then this function represents the substitution [sigma] in the context Gamma'.
All variables of Delta are ignored and substitutes of the variables of Gamma'
are unshifted. This may therefore raise UnshiftExn in case substitutes of
variables of Gamma' refers to variables of Delta.
*)
let subst2 (sigma:t) (i:int) =
fun _ _ n nargs k ->
let (argmin,t) = IntMap.find (n+i+1-k) sigma in
if nargs >= argmin then Subst.shift k (Subst.unshift (i+1) t) else raise Not_found

let apply' (sigma:t) : int -> term -> term*bool =
if is_identity sigma then (fun _ t -> t,false) else apply_exsubst (subst sigma)

let apply2' (sigma:t) (i:int) : int -> term -> term*bool =
if is_identity sigma then (fun _ t -> t,false) else apply_exsubst (subst2 sigma i)

let apply = fun sigma i t -> fst (apply' sigma i t)

let apply2 = fun sigma n i t -> fst (apply2' sigma n i t)

let add (sigma:t) (n:int) (nargs:int) (t:term) : t =
assert ( not (IntMap.mem n sigma) || fst (IntMap.find n sigma) > nargs );
if not (IntMap.mem n sigma) || fst (IntMap.find n sigma) > nargs
then IntMap.add n (nargs,t) sigma else sigma

let applys (sigma:t) : t -> t*bool =
if is_identity sigma then (fun t -> t,false)
else fun sigma' ->
let modified = ref false in
let applysigma (n,t) =
let res,flag = apply' sigma 0 t in
if flag then modified := true;
(n,res)
in
IntMap.map applysigma sigma', !modified

let rec mk_idempotent (sigma:t) : t =
let sigma', flag = applys sigma sigma in
if flag then mk_idempotent sigma' else sigma

let pp (name:(int->ident)) (fmt:formatter) (sigma:t) : unit =
let pp_aux i (n,t) =
fprintf fmt " %a[%i](%i args) -> %a\n" pp_ident (name i) i n pp_term t in
IntMap.iter pp_aux sigma

end
46 changes: 46 additions & 0 deletions kernel/exsubst.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
open Term

(** This modules implements extended substitution of DB variables in a term.
This is typically used to:
1) infer a "most general" typing substitution from constraints gathered while
inferring the type of the LHS of a rule.
2) apply the substitution to the RHS of the rule before typechecking it.
*)
module ExSubst :
sig
type t

val identity : t
(** Empty substitution *)

val is_identity : t -> bool
(** Checks emptyness *)

val add : t -> int -> int -> term -> t
(** [add sigma n t] returns the substitution [sigma] with the extra mapping [n] -> [t]. *)

val apply : t -> int -> term -> term
(** [apply sigma n t] applies the subsitution [sigma] to [t] considered
under [n] lambda abstractions. *)

val apply' : t -> int -> term -> term*bool
(** Same as apply, but outputting a boolean [true] if the term is modified
by the substitution. *)

val apply2 : t -> int -> int -> term -> term
(** Special substitution function corresponding to given ExSubst.t instance [sigma]
"in a smaller context":
Assume [sigma] a substitution in a context Gamma = Gamma' ; Delta with |Delta|=[i].
Then this function represents the substitution [sigma] in the context Gamma'.
All variables of Delta are ignored and substitutes of the variables of Gamma'
are unshifted. This may therefore raise UnshiftExn in case substitutes of
variables of Gamma' refers to variables of Delta.
*)

val mk_idempotent : t -> t
(** [mk_idempotent sigma] successively applies sigma to its mapped terms until this operation
has no effect anymore. *)

val pp : (int->Basic.ident) -> t Basic.printer
(** Prints the substitution using given naming function *)
end
Loading