@@ -6,7 +6,6 @@ open EcTypes
66open EcDecl
77open EcCoreFol
88
9- module PE = EcPrinting
109module EP = EcPath
1110module FL = EcCoreFol
1211
@@ -84,45 +83,23 @@ let datatype_ind_path (mode : indmode) (p : EcPath.path) =
8483 EcPath. pqoname (EcPath. prefix p) name
8584
8685(* -------------------------------------------------------------------- *)
87- type variant = Concrete | Record of symbol | Variant of symbol
86+ type non_positive_intype = Concrete | Record of symbol | Variant of symbol
8887
89- type context =
90- | InType of variant
88+ type non_positive_description =
89+ | InType of EcIdent .ident option * non_positive_intype
9190 | NonPositiveOcc of ty
9291 | AbstractTypeRestriction
9392 | TypePositionRestriction of ty
9493
95- exception NonPositiveCtx of ( EP. path * context ) list
94+ type non_positive_context = ( symbol * non_positive_description ) list
9695
97- exception NonPositive of ( PE.PPEnv. t -> unit PE. pp)
96+ exception NonPositive of non_positive_context
9897
99- let render_context pp fmt (p , ctx ) = match ctx with
100- | InType Concrete -> Format. fprintf fmt " ... in type %a" PE. pp_path p
101- | InType (Record s ) ->
102- Format. fprintf fmt " ... in record field %s of type %a" s PE. pp_path p
103- | InType (Variant s ) ->
104- Format. fprintf fmt " ... in variant %s of type %a" s PE. pp_path p
105- | NonPositiveOcc ty ->
106- Format. fprintf fmt " non-positive occurrence of %a in type %a"
107- (PE. pp_type pp) ty PE. pp_path p
108- | AbstractTypeRestriction ->
109- Format. fprintf fmt " unauthorised abstract type constructor %a" PE. pp_path p
110- | TypePositionRestriction ty ->
111- Format. fprintf fmt
112- " recursive occurrence %a in the definition of %a has different \
113- arguments, which is not allowed."
114- (PE. pp_type pp) ty PE. pp_path p
98+ let with_context ?ident p ctx f =
99+ try f () with NonPositive l -> raise (NonPositive ((EP. basename p, InType (ident, ctx)) :: l))
115100
116- let render_context_list p l pp fmt () =
117- Format. fprintf fmt " Could not verify strict positivity of type %a:@;@[<v 2>" PE. pp_path p;
118- Format. pp_print_list (render_context pp) fmt l;
119- Format. fprintf fmt " @;@]"
120-
121-
122- let with_context p ctx f =
123- try f () with NonPositiveCtx l -> raise (NonPositiveCtx ((p, ctx) :: l))
124-
125- let non_positive p ctx = raise (NonPositiveCtx [(p, ctx)])
101+ let non_positive (p : EP.path ) ctx = raise (NonPositive [(EP. basename p, ctx)])
102+ let non_positive' (s : EcIdent.ident ) ctx = raise (NonPositive [(s.id_symb, ctx)])
126103
127104(* * below, [fct] designates the function that takes a path to a type constructor
128105 and returns the corresponding type declaration *)
@@ -165,15 +142,15 @@ let rec check_positivity_in_decl fct p decl ident =
165142 and iter l f = List. iter f l in
166143
167144 match decl.tyd_type with
168- | Concrete ty -> with_context p ( InType Concrete ) (check ty)
145+ | Concrete ty -> with_context ~ident p Concrete (check ty)
169146 | Abstract _ -> non_positive p AbstractTypeRestriction
170147 | Datatype { tydt_ctors } ->
171148 iter tydt_ctors @@ fun (name , argty ) ->
172149 iter argty @@ fun ty ->
173- with_context p (InType ( Variant name) ) (check ty)
150+ with_context ~ident p (Variant name) (check ty)
174151 | Record (_ , tys ) ->
175152 iter tys @@ fun (name , ty ) ->
176- with_context p (InType ( Record name) ) (check ty)
153+ with_context ~ident p (Record name) (check ty)
177154
178155(* * Ensures all occurrences of type variable [ident] are positive in type [ty] *)
179156and check_positivity_ident fct p params ident ty =
@@ -186,17 +163,17 @@ and check_positivity_ident fct p params ident ty =
186163 | Tconstr (q , args ) ->
187164 let decl = fct q in
188165 List. combine args decl.tyd_params
189- |> List. filter_map (fun (arg , (ident , _ )) ->
190- if EcTypes. var_mem ident arg then Some ident else None )
166+ |> List. filter_map (fun (arg , (ident' , _ )) ->
167+ if EcTypes. var_mem ident arg then Some ident' else None )
191168 |> List. iter (check_positivity_in_decl fct q decl)
192169 | Tfun (from , to_ ) ->
193- if EcTypes. var_mem ident from then non_positive p (NonPositiveOcc ty);
170+ if EcTypes. var_mem ident from then non_positive' ident (NonPositiveOcc ty);
194171 check_positivity_ident fct p params ident to_
195172
196173(* * Ensures all occurrences of path [p] are positive in type [ty] *)
197174let rec check_positivity_path fct p ty =
198175 match ty.ty_node with
199- | Tglob _ | Tunivar _ | Tvar _ -> ()
176+ | Tglob _ | Tunivar _ | Tvar _ -> ()
200177 | Ttuple tys -> List. iter (check_positivity_path fct p) tys
201178 | Tconstr (q , args ) when EcPath. p_equal q p ->
202179 if List. exists (occurs p) args then non_positive p (NonPositiveOcc ty)
@@ -211,10 +188,11 @@ let rec check_positivity_path fct p ty =
211188 check_positivity_path fct p to_
212189
213190let check_positivity fct dt =
214- let tys = List. flatten (List. map snd dt.dt_ctors) in
215- try List. iter (check_positivity_path fct dt.dt_path) tys
216- with NonPositiveCtx l ->
217- raise (NonPositive (render_context_list dt.dt_path l))
191+ let check ty () = check_positivity_path fct dt.dt_path ty
192+ and iter l f = List. iter f l in
193+ iter dt.dt_ctors @@ fun (name , argty ) ->
194+ iter argty @@ fun ty ->
195+ with_context dt.dt_path (Variant name) (check ty)
218196
219197let indsc_of_datatype ?(normty = identity) (mode : indmode ) (dt : datatype ) =
220198 let tpath = dt.dt_path in
0 commit comments