1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
open Util
open Names
open Constr
open Declarations
open Environ
open Context
module RelDecl = Context.Rel.Declaration
let relevance_of_rel env n =
let decl = lookup_rel n env in
RelDecl.get_relevance decl
let relevance_of_var env x =
let decl = lookup_named x env in
Context.Named.Declaration.get_relevance decl
let relevance_of_constant env c =
let decl = lookup_constant c env in
decl.const_relevance
let relevance_of_constructor env ((mi,i),_) =
let decl = lookup_mind mi env in
let packet = decl.mind_packets.(i) in
packet.mind_relevance
let relevance_of_projection env p =
let mind = Projection.mind p in
let mib = lookup_mind mind env in
Declareops.relevance_of_projection_repr mib (Projection.repr p)
let rec relevance_of_rel_extra env extra n =
match extra with
| [] -> relevance_of_rel env n
| r :: _ when Int.equal n 1 -> r
| _ :: extra -> relevance_of_rel_extra env extra (n-1)
let relevance_of_flex env extra lft = function
| ConstKey (c,_) -> relevance_of_constant env c
| VarKey x -> relevance_of_var env x
| RelKey p -> relevance_of_rel_extra env extra (Esubst.reloc_rel p lft)
let rec relevance_of_fterm env extra lft f =
let open CClosure in
match CClosure.relevance_of f with
| KnownR -> Sorts.Relevant
| KnownI -> Sorts.Irrelevant
| Unknown ->
let r = match fterm_of f with
| FRel n -> relevance_of_rel_extra env extra (Esubst.reloc_rel n lft)
| FAtom c -> relevance_of_term_extra env extra lft (Esubst.subs_id 0) c
| FFlex key -> relevance_of_flex env extra lft key
| FInt _ -> Sorts.Relevant
| FInd _ | FProd _ -> Sorts.Relevant (* types are always relevant *)
| FConstruct (c,_) -> relevance_of_constructor env c
| FApp (f, _) -> relevance_of_fterm env extra lft f
| FProj (p, _) -> relevance_of_projection env p
| FFix (((_,i),(lna,_,_)), _) -> (lna.(i)).binder_relevance
| FCoFix ((i,(lna,_,_)), _) -> (lna.(i)).binder_relevance
| FCaseT (ci, _, _, _, _) -> ci.ci_relevance
| FLambda (len, tys, bdy, e) ->
let extra = List.rev_append (List.map (fun (x,_) -> binder_relevance x) tys) extra in
let lft = Esubst.el_liftn len lft in
let e = Esubst.subs_liftn len e in
relevance_of_term_extra env extra lft e bdy
| FLetIn (x, _, _, bdy, e) ->
relevance_of_term_extra env (x.binder_relevance :: extra)
(Esubst.el_lift lft) (Esubst.subs_lift e) bdy
| FLIFT (k, f) -> relevance_of_fterm env extra (Esubst.el_shft k lft) f
| FCLOS (c, e) -> relevance_of_term_extra env extra lft e c
| FEvar (_, _) -> Sorts.Relevant (* let's assume evars are relevant for now *)
| FLOCKED -> assert false
in
CClosure.set_relevance r f;
r
and relevance_of_term_extra env extra lft subs c =
match kind c with
| Rel n ->
(match Esubst.expand_rel n subs with
| Inl (k, f) -> relevance_of_fterm env extra (Esubst.el_liftn k lft) f
| Inr (n, _) -> relevance_of_rel_extra env extra (Esubst.reloc_rel n lft))
| Var x -> relevance_of_var env x
| Sort _ | Ind _ | Prod _ -> Sorts.Relevant (* types are always relevant *)
| Cast (c, _, _) -> relevance_of_term_extra env extra lft subs c
| Lambda ({binder_relevance=r;_}, _, bdy) ->
relevance_of_term_extra env (r::extra) (Esubst.el_lift lft) (Esubst.subs_lift subs) bdy
| LetIn ({binder_relevance=r;_}, _, _, bdy) ->
relevance_of_term_extra env (r::extra) (Esubst.el_lift lft) (Esubst.subs_lift subs) bdy
| App (c, _) -> relevance_of_term_extra env extra lft subs c
| Const (c,_) -> relevance_of_constant env c
| Construct (c,_) -> relevance_of_constructor env c
| Case (ci, _, _, _) -> ci.ci_relevance
| Fix ((_,i),(lna,_,_)) -> (lna.(i)).binder_relevance
| CoFix (i,(lna,_,_)) -> (lna.(i)).binder_relevance
| Proj (p, _) -> relevance_of_projection env p
| Int _ -> Sorts.Relevant
| Meta _ | Evar _ -> Sorts.Relevant (* let's assume metas and evars are relevant for now *)
let relevance_of_fterm env extra lft c =
if Environ.sprop_allowed env then relevance_of_fterm env extra lft c
else Sorts.Relevant
let relevance_of_term env c =
if Environ.sprop_allowed env
then relevance_of_term_extra env [] Esubst.el_id (Esubst.subs_id 0) c
else Sorts.Relevant
|