Skip to content

Commit 89f2dba

Browse files
committed
feat: new strict-positivity checking for datatypes
style: use regular datatype for ty_body fix: correct spelling of 'instantiate' The spelling 'instanciate' is only acknowledged in the Wiktionary, while all other dictionaries prefer the spelling with a 't'. ex.: https://dictionary.cambridge.org/dictionary/english/instantiate feat: working stack-based pretty-printing, with extended capacities I still need to understand clearly the behaviour of `Format` boxes, which remain quite mysterious. I also have to add a test file for coverage. fix: perform positivity check in type arguments of type constructors test: add a simple test file for positivity checking.
1 parent 322e303 commit 89f2dba

29 files changed

+366
-158
lines changed

src/ecCoreSubst.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type mod_extra = {
1414
mex_glob : memory -> form;
1515
}
1616

17-
type sc_instanciate = {
17+
type sc_instantiate = {
1818
sc_memtype : memtype;
1919
sc_mempred : mem_pr Mid.t;
2020
sc_expr : expr Mid.t;

src/ecCoreSubst.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ open EcCoreModules
88
open EcCoreFol
99

1010
(* -------------------------------------------------------------------- *)
11-
type sc_instanciate = {
11+
type sc_instantiate = {
1212
sc_memtype : memtype;
1313
sc_mempred : mem_pr Mid.t;
1414
sc_expr : expr Mid.t;

src/ecDecl.ml

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,42 +15,42 @@ type ty_param = EcIdent.t * EcPath.Sp.t
1515
type ty_params = ty_param list
1616
type ty_pctor = [ `Int of int | `Named of ty_params ]
1717

18-
type tydecl = {
19-
tyd_params : ty_params;
20-
tyd_type : ty_body;
21-
tyd_loca : locality;
22-
}
23-
24-
and ty_body = [
25-
| `Concrete of EcTypes.ty
26-
| `Abstract of Sp.t
27-
| `Datatype of ty_dtype
28-
| `Record of ty_record
29-
]
30-
31-
and ty_record =
18+
type ty_record =
3219
EcCoreFol.form * (EcSymbols.symbol * EcTypes.ty) list
3320

34-
and ty_dtype_ctor =
21+
type ty_dtype_ctor =
3522
EcSymbols.symbol * EcTypes.ty list
3623

37-
and ty_dtype = {
24+
type ty_dtype = {
3825
tydt_ctors : ty_dtype_ctor list;
3926
tydt_schelim : EcCoreFol.form;
4027
tydt_schcase : EcCoreFol.form;
4128
}
4229

30+
type ty_body =
31+
| Concrete of EcTypes.ty
32+
| Abstract of Sp.t
33+
| Datatype of ty_dtype
34+
| Record of ty_record
35+
36+
37+
type tydecl = {
38+
tyd_params : ty_params;
39+
tyd_type : ty_body;
40+
tyd_loca : locality;
41+
}
42+
4343
let tydecl_as_concrete (td : tydecl) =
44-
match td.tyd_type with `Concrete x -> Some x | _ -> None
44+
match td.tyd_type with Concrete x -> Some x | _ -> None
4545

4646
let tydecl_as_abstract (td : tydecl) =
47-
match td.tyd_type with `Abstract x -> Some x | _ -> None
47+
match td.tyd_type with Abstract x -> Some x | _ -> None
4848

4949
let tydecl_as_datatype (td : tydecl) =
50-
match td.tyd_type with `Datatype x -> Some x | _ -> None
50+
match td.tyd_type with Datatype x -> Some x | _ -> None
5151

5252
let tydecl_as_record (td : tydecl) =
53-
match td.tyd_type with `Record x -> Some x | _ -> None
53+
match td.tyd_type with Record (x, y) -> Some (x, y) | _ -> None
5454

5555
(* -------------------------------------------------------------------- *)
5656
let abs_tydecl ?(tc = Sp.empty) ?(params = `Int 0) lc =
@@ -65,10 +65,10 @@ let abs_tydecl ?(tc = Sp.empty) ?(params = `Int 0) lc =
6565
(EcUid.NameGen.bulk ~fmt n)
6666
in
6767

68-
{ tyd_params = params; tyd_type = `Abstract tc; tyd_loca = lc; }
68+
{ tyd_params = params; tyd_type = Abstract tc; tyd_loca = lc; }
6969

7070
(* -------------------------------------------------------------------- *)
71-
let ty_instanciate (params : ty_params) (args : ty list) (ty : ty) =
71+
let ty_instantiate (params : ty_params) (args : ty list) (ty : ty) =
7272
let subst = CS.Tvar.init (List.map fst params) args in
7373
CS.Tvar.subst subst ty
7474

src/ecDecl.mli

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,39 @@ type ty_param = EcIdent.t * EcPath.Sp.t
1111
type ty_params = ty_param list
1212
type ty_pctor = [ `Int of int | `Named of ty_params ]
1313

14-
type tydecl = {
15-
tyd_params : ty_params;
16-
tyd_type : ty_body;
17-
tyd_loca : locality;
18-
}
19-
20-
and ty_body = [
21-
| `Concrete of EcTypes.ty
22-
| `Abstract of Sp.t
23-
| `Datatype of ty_dtype
24-
| `Record of ty_record
25-
]
26-
27-
and ty_record =
14+
type ty_record =
2815
EcCoreFol.form * (EcSymbols.symbol * EcTypes.ty) list
2916

30-
and ty_dtype_ctor =
17+
type ty_dtype_ctor =
3118
EcSymbols.symbol * EcTypes.ty list
3219

33-
and ty_dtype = {
20+
type ty_dtype = {
3421
tydt_ctors : ty_dtype_ctor list;
3522
tydt_schelim : EcCoreFol.form;
3623
tydt_schcase : EcCoreFol.form;
3724
}
3825

26+
type ty_body =
27+
| Concrete of EcTypes.ty
28+
| Abstract of Sp.t
29+
| Datatype of ty_dtype
30+
| Record of ty_record
31+
32+
33+
type tydecl = {
34+
tyd_params : ty_params;
35+
tyd_type : ty_body;
36+
tyd_loca : locality;
37+
}
38+
3939
val tydecl_as_concrete : tydecl -> EcTypes.ty option
4040
val tydecl_as_abstract : tydecl -> Sp.t option
4141
val tydecl_as_datatype : tydecl -> ty_dtype option
4242
val tydecl_as_record : tydecl -> (form * (EcSymbols.symbol * EcTypes.ty) list) option
4343

4444
val abs_tydecl : ?tc:Sp.t -> ?params:ty_pctor -> locality -> tydecl
4545

46-
val ty_instanciate : ty_params -> ty list -> ty -> ty
46+
val ty_instantiate : ty_params -> ty list -> ty -> ty
4747

4848
(* -------------------------------------------------------------------- *)
4949
type locals = EcIdent.t list

src/ecEnv.ml

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -781,10 +781,10 @@ module MC = struct
781781
let loca = tyd.tyd_loca in
782782

783783
match tyd.tyd_type with
784-
| `Concrete _ -> mc
785-
| `Abstract _ -> mc
784+
| Concrete _ -> mc
785+
| Abstract _ -> mc
786786

787-
| `Datatype dtype ->
787+
| Datatype dtype ->
788788
let cs = dtype.tydt_ctors in
789789
let schelim = dtype.tydt_schelim in
790790
let schcase = dtype.tydt_schcase in
@@ -828,7 +828,7 @@ module MC = struct
828828
_up_operator candup mc name (ipath name, op)
829829
) mc projs
830830

831-
| `Record (scheme, fields) ->
831+
| Record (scheme, fields) ->
832832
let params = List.map (fun (x, _) -> tvar x) tyd.tyd_params in
833833
let nfields = List.length fields in
834834
let cfields =
@@ -2544,12 +2544,12 @@ module Ty = struct
25442544
25452545
let defined (name : EcPath.path) (env : env) =
25462546
match by_path_opt name env with
2547-
| Some { tyd_type = `Concrete _ } -> true
2547+
| Some { tyd_type = Concrete _ } -> true
25482548
| _ -> false
25492549
25502550
let unfold (name : EcPath.path) (args : EcTypes.ty list) (env : env) =
25512551
match by_path_opt name env with
2552-
| Some ({ tyd_type = `Concrete body } as tyd) ->
2552+
| Some ({ tyd_type = Concrete body } as tyd) ->
25532553
Tvar.subst
25542554
(Tvar.init (List.map fst tyd.tyd_params) args)
25552555
body
@@ -2585,14 +2585,15 @@ module Ty = struct
25852585
match ty.ty_node with
25862586
| Tconstr (p, tys) -> begin
25872587
match by_path_opt p env with
2588-
| Some ({ tyd_type = (`Datatype _ | `Record _) as body }) ->
2588+
| Some ({ tyd_type = (Datatype _ | Record _) as body }) ->
25892589
let prefix = EcPath.prefix p in
25902590
let basename = EcPath.basename p in
25912591
let basename =
25922592
match body, mode with
2593-
| `Record _, (`Ind | `Case) -> basename ^ "_ind"
2594-
| `Datatype _, `Ind -> basename ^ "_ind"
2595-
| `Datatype _, `Case -> basename ^ "_case"
2593+
| Record _, (`Ind | `Case) -> basename ^ "_ind"
2594+
| Datatype _, `Ind -> basename ^ "_ind"
2595+
| Datatype _, `Case -> basename ^ "_case"
2596+
| _, _ -> assert false
25962597
in
25972598
Some (EcPath.pqoname prefix basename, tys)
25982599
| _ -> None
@@ -2608,7 +2609,7 @@ module Ty = struct
26082609
let env = MC.bind_tydecl name ty env in
26092610
26102611
match ty.tyd_type with
2611-
| `Abstract tc ->
2612+
| Abstract tc ->
26122613
let myty =
26132614
let myp = EcPath.pqname (root env) name in
26142615
let typ = List.map (fst_map EcIdent.fresh) ty.tyd_params in
@@ -2814,7 +2815,7 @@ module Ax = struct
28142815
let rebind name ax env =
28152816
MC.bind_axiom name ax env
28162817
2817-
let instanciate p tys env =
2818+
let instantiate p tys env =
28182819
match by_path_opt p env with
28192820
| Some ({ ax_spec = f } as ax) ->
28202821
Tvar.f_subst ~freshen:true (List.map fst ax.ax_tparams) tys f
@@ -2934,7 +2935,7 @@ module Theory = struct
29342935
29352936
| Th_type (x, tyd) -> begin
29362937
match tyd.tyd_type with
2937-
| `Abstract tc ->
2938+
| Abstract tc ->
29382939
let myty =
29392940
let typ = List.map (fst_map EcIdent.fresh) tyd.tyd_params in
29402941
(typ, EcTypes.tconstr (xpath x) (List.map (tvar |- fst) typ))

src/ecEnv.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ module Ax : sig
168168
val iter : ?name:qsymbol -> (path -> t -> unit) -> env -> unit
169169
val all : ?check:(path -> t -> bool) -> ?name:qsymbol -> env -> (path * t) list
170170

171-
val instanciate : path -> EcTypes.ty list -> env -> form
171+
val instantiate : path -> EcTypes.ty list -> env -> form
172172
end
173173

174174
(* -------------------------------------------------------------------- *)

src/ecFol.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ val f_ty_app : EcEnv.env -> form -> form list -> form
116116

117117
(* -------------------------------------------------------------------- *)
118118
(* WARNING : this function should be use only in a context ensuring
119-
* that the quantified variables can be instanciated *)
119+
* that the quantified variables can be instantiated *)
120120

121121
val f_betared : form -> form
122122

src/ecHiInductive.ml

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ type dterror =
2323
| DTE_TypeError of TT.tyerror
2424
| DTE_DuplicatedCtor of symbol
2525
| DTE_InvalidCTorType of symbol * TT.tyerror
26-
| DTE_NonPositive
26+
| DTE_NonPositive of symbol * EI.non_positive_context
2727
| DTE_Empty
2828

2929
type fxerror =
@@ -52,7 +52,7 @@ let trans_record (env : EcEnv.env) (name : ptydname) (rc : precord) =
5252
Msym.odup unloc (List.map fst rc) |> oiter (fun (x, y) ->
5353
rcerror y.pl_loc env (RCE_DuplicatedField x.pl_desc));
5454

55-
(* Check for emptyness *)
55+
(* Check for emptiness *)
5656
if List.is_empty rc then
5757
rcerror loc env RCE_Empty;
5858

@@ -84,7 +84,7 @@ let trans_datatype (env : EcEnv.env) (name : ptydname) (dt : pdatatype) =
8484
let env0 =
8585
let myself = {
8686
tyd_params = EcUnify.UniEnv.tparams ue;
87-
tyd_type = `Abstract EcPath.Sp.empty;
87+
tyd_type = Abstract EcPath.Sp.empty;
8888
tyd_loca = lc;
8989
} in
9090
EcEnv.Ty.bind (unloc name) myself env
@@ -106,7 +106,7 @@ let trans_datatype (env : EcEnv.env) (name : ptydname) (dt : pdatatype) =
106106
dt |> List.map for1
107107
in
108108

109-
(* Check for emptyness *)
109+
(* Check for emptiness *)
110110
begin
111111
let rec isempty_n (ctors : (ty list) list) =
112112
List.for_all isempty_1 ctors
@@ -131,21 +131,24 @@ let trans_datatype (env : EcEnv.env) (name : ptydname) (dt : pdatatype) =
131131

132132
let tdecl = EcEnv.Ty.by_path_opt tname env0
133133
|> odfl (EcDecl.abs_tydecl ~params:(`Named tparams) lc) in
134-
let tyinst () =
135-
fun ty -> ty_instanciate tdecl.tyd_params targs ty in
134+
let tyinst = ty_instantiate tdecl.tyd_params targs in
136135

137136
match tdecl.tyd_type with
138-
| `Abstract _ ->
139-
List.exists isempty (targs)
137+
| Abstract _ ->
138+
List.exists isempty targs
140139

141-
| `Concrete ty ->
142-
isempty_1 [tyinst () ty]
140+
| Concrete ty ->
141+
isempty_1 [ tyinst ty ]
143142

144-
| `Record (_, fields) ->
145-
isempty_1 (List.map (tyinst () |- snd) fields)
143+
| Record (_, fields) ->
144+
isempty_1 (List.map (tyinst |- snd) fields)
146145

147-
| `Datatype dt ->
148-
isempty_n (List.map (List.map (tyinst ()) |- snd) dt.tydt_ctors)
146+
| Datatype dt ->
147+
(* FIXME: Inspecting all constructors recursively causes
148+
non-termination in some cases. One can have the same
149+
limitation as is done for positivity in order to limit this
150+
unfolding to well-behaved cases. *)
151+
isempty_n (List.map (List.map tyinst |- snd) dt.tydt_ctors)
149152

150153
in
151154

src/ecHiInductive.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type dterror =
1616
| DTE_TypeError of EcTyping.tyerror
1717
| DTE_DuplicatedCtor of symbol
1818
| DTE_InvalidCTorType of symbol * EcTyping.tyerror
19-
| DTE_NonPositive
19+
| DTE_NonPositive of symbol * non_positive_context
2020
| DTE_Empty
2121

2222
type fxerror =

0 commit comments

Comments
 (0)