aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--contrib/interface/xlate.ml2
-rw-r--r--doc/refman/RefMan-oth.tex9
-rw-r--r--parsing/g_vernac.ml49
-rw-r--r--parsing/ppvernac.ml9
-rw-r--r--parsing/prettyp.ml19
-rw-r--r--proofs/redexpr.ml64
-rw-r--r--proofs/redexpr.mli6
-rw-r--r--test-suite/complexity/ring2.v51
-rw-r--r--toplevel/vernacentries.ml21
-rw-r--r--toplevel/vernacexpr.ml3
10 files changed, 160 insertions, 33 deletions
diff --git a/contrib/interface/xlate.ml b/contrib/interface/xlate.ml
index b3909d317..169ec0dc2 100644
--- a/contrib/interface/xlate.ml
+++ b/contrib/interface/xlate.ml
@@ -1796,7 +1796,7 @@ let rec xlate_vernac =
ctf_ID_OPT_SOME (xlate_ident s))
| VernacEndProof Admitted ->
CT_save (CT_coerce_THM_to_THM_OPT (CT_thm "Admitted"), ctv_ID_OPT_NONE)
- | VernacSetOpacity l ->
+ | VernacSetOpacity (_,l) ->
CT_strategy(CT_level_list
(List.map (fun (l,q) ->
(level_to_ct_LEVEL l,
diff --git a/doc/refman/RefMan-oth.tex b/doc/refman/RefMan-oth.tex
index afe31d0d2..9a17c0f3c 100644
--- a/doc/refman/RefMan-oth.tex
+++ b/doc/refman/RefMan-oth.tex
@@ -135,7 +135,8 @@ environment}\\
\ref{Theorem}
-\subsection{\tt Strategy {\it level} [ \qualid$_1$ \dots \qualid$_n$ ].\comindex{Strategy}\label{Strategy}}
+\subsection{\tt Strategy {\it level} [ \qualid$_1$ \dots \qualid$_n$
+ ].\comindex{Strategy}\comindex{Local Strategy}\label{Strategy}}
This command generalizes the behaviour of {\tt Opaque} and {\tt
Transaparent} commands. It is used to fine-tune the strategy for
unfolding constants, both at the tactic level and at the kernel
@@ -159,8 +160,10 @@ Levels can be one of the following (higher to lower):
(behaves like $-\infty$)
\end{description}
-The behaviour regarding sections and modules is the same as for the
-{\tt Transparent} command.
+These directives survive section and module closure, unless the
+command is prefixed by {\tt Local}. In the latter case, the behaviour
+regarding sections and modules is the same as for the {\tt
+ Transparent} and {\tt Opaque} commands.
\subsection[\tt Search {\qualid}.]{\tt Search {\qualid}.\comindex{Search}}
This command displays the name and type of all theorems of the current
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index 27f80fd75..437ef58fd 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -447,12 +447,15 @@ GEXTEND Gram
gallina_ext:
[ [ (* Transparent and Opaque *)
IDENT "Transparent"; l = LIST1 global ->
- VernacSetOpacity [Conv_oracle.transparent,l]
+ VernacSetOpacity (true,[Conv_oracle.transparent,l])
| IDENT "Opaque"; l = LIST1 global ->
- VernacSetOpacity [Conv_oracle.Opaque, l]
+ VernacSetOpacity (true,[Conv_oracle.Opaque, l])
| IDENT "Strategy"; l =
LIST1 [ lev=strategy_level; "["; q=LIST1 global; "]" -> (lev,q)] ->
- VernacSetOpacity l
+ VernacSetOpacity (false,l)
+ | IDENT "Local"; IDENT "Strategy"; l =
+ LIST1 [ lev=strategy_level; "["; q=LIST1 global; "]" -> (lev,q)] ->
+ VernacSetOpacity (true,l)
(* Canonical structure *)
| IDENT "Canonical"; IDENT "Structure"; qid = global ->
VernacCanonical qid
diff --git a/parsing/ppvernac.ml b/parsing/ppvernac.ml
index afa28768f..c31defe09 100644
--- a/parsing/ppvernac.ml
+++ b/parsing/ppvernac.ml
@@ -829,13 +829,13 @@ let rec pr_vernac = function
str (if List.length idl > 1 then "s " else " ") ++
prlist_with_sep spc pr_lident idl ++ str " :" ++ spc () ++
pr_lconstr c)
- | VernacSetOpacity[k,l] when k=Conv_oracle.transparent ->
+ | VernacSetOpacity(true,[k,l]) when k=Conv_oracle.transparent ->
hov 1 (str"Transparent" ++
spc() ++ prlist_with_sep sep pr_reference l)
- | VernacSetOpacity[Conv_oracle.Opaque,l] ->
+ | VernacSetOpacity(true,[Conv_oracle.Opaque,l]) ->
hov 1 (str"Opaque" ++
spc() ++ prlist_with_sep sep pr_reference l)
- | VernacSetOpacity l ->
+ | VernacSetOpacity (local,l) ->
let pr_lev = function
Conv_oracle.Opaque -> str"opaque"
| Conv_oracle.Expand -> str"expand"
@@ -844,7 +844,8 @@ let rec pr_vernac = function
let pr_line (l,q) =
hov 2 (pr_lev l ++ spc() ++
str"[" ++ prlist_with_sep sep pr_reference q ++ str"]") in
- hov 1 (str"Strategy" ++ spc() ++ hv 0 (prlist_with_sep sep pr_line l))
+ hov 1 (pr_locality local ++ str"Strategy" ++ spc() ++
+ hv 0 (prlist_with_sep sep pr_line l))
| VernacUnsetOption na ->
hov 1 (str"Unset" ++ spc() ++ pr_printoption na None)
| VernacSetOption (na,v) -> hov 2 (str"Set" ++ spc() ++ pr_set_option na v)
diff --git a/parsing/prettyp.ml b/parsing/prettyp.ml
index dc242e8ca..bdbd74b0f 100644
--- a/parsing/prettyp.ml
+++ b/parsing/prettyp.ml
@@ -112,18 +112,17 @@ let need_expansion impl ref =
type opacity =
| FullyOpaque
- | TransparentMaybeOpacified of bool
+ | TransparentMaybeOpacified of Conv_oracle.level
let opacity env = function
| VarRef v when pi2 (Environ.lookup_named v env) <> None ->
- Some (TransparentMaybeOpacified
- (not (Reductionops.is_transparent(VarKey v))))
+ Some(TransparentMaybeOpacified (Conv_oracle.get_strategy(VarKey v)))
| ConstRef cst ->
let cb = Environ.lookup_constant cst env in
if cb.const_body = None then None
else if cb.const_opaque then Some FullyOpaque
- else Some (TransparentMaybeOpacified
- (not(Reductionops.is_transparent(ConstKey cst))))
+ else Some
+ (TransparentMaybeOpacified (Conv_oracle.get_strategy(ConstKey cst)))
| _ -> None
let print_opacity ref =
@@ -132,8 +131,14 @@ let print_opacity ref =
| Some s -> pr_global ref ++ str " is " ++
str (match s with
| FullyOpaque -> "opaque"
- | TransparentMaybeOpacified true -> "basically transparent but considered opaque for reduction"
- | TransparentMaybeOpacified false -> "transparent") ++ fnl()
+ | TransparentMaybeOpacified Conv_oracle.Opaque ->
+ "basically transparent but considered opaque for reduction"
+ | TransparentMaybeOpacified lev when lev = Conv_oracle.transparent ->
+ "transparent"
+ | TransparentMaybeOpacified (Conv_oracle.Level n) ->
+ "transparent (with expansion weight "^string_of_int n^")"
+ | TransparentMaybeOpacified Conv_oracle.Expand ->
+ "transparent (with minimal expansion weight)") ++ fnl()
let print_name_infos ref =
let impl = implicits_of_global ref in
diff --git a/proofs/redexpr.ml b/proofs/redexpr.ml
index 28e121ab2..27db71755 100644
--- a/proofs/redexpr.ml
+++ b/proofs/redexpr.ml
@@ -19,14 +19,19 @@ open Reductionops
open Tacred
open Closure
open RedFlags
-
+open Libobject
(* call by value normalisation function using the virtual machine *)
let cbv_vm env _ c =
let ctyp = (fst (Typeops.infer env c)).Environ.uj_type in
Vnorm.cbv_vm env c ctyp
-let set_strategy k l =
+
+let set_strategy_one ref l =
+ let k =
+ match ref with
+ | EvalConstRef sp -> ConstKey sp
+ | EvalVarRef id -> VarKey id in
Conv_oracle.set_strategy k l;
match k,l with
ConstKey sp, Conv_oracle.Opaque ->
@@ -41,6 +46,61 @@ let set_strategy k l =
Csymtable.set_transparent_const sp
| _ -> ()
+let cache_strategy str =
+ List.iter
+ (fun (lev,ql) -> List.iter (fun q -> set_strategy_one q lev) ql)
+ str
+
+let subst_strategy (_,subs,obj) =
+ list_smartmap
+ (fun (k,ql as entry) ->
+ let ql' = list_smartmap (Mod_subst.subst_evaluable_reference subs) ql in
+ if ql==ql' then entry else (k,ql'))
+ obj
+
+
+let map_strategy f l =
+ let l' = List.fold_right
+ (fun (lev,ql) str ->
+ let ql' = List.fold_right
+ (fun q ql ->
+ match f q with
+ Some q' -> q' :: ql
+ | None -> ql) ql [] in
+ if ql'=[] then str else (lev,ql')::str) l [] in
+ if l'=[] then None else Some l'
+
+let export_strategy obj =
+ map_strategy (function
+ EvalVarRef _ -> None
+ | EvalConstRef _ as q -> Some q) obj
+
+let classify_strategy (_,obj) = Substitute obj
+
+let disch_ref ref =
+ match ref with
+ EvalConstRef c ->
+ let c' = Lib.discharge_con c in
+ if c==c' then Some ref else Some (EvalConstRef c')
+ | _ -> Some ref
+
+let discharge_strategy (_,obj) =
+ map_strategy disch_ref obj
+
+let (inStrategy,outStrategy) =
+ declare_object {(default_object "STRATEGY") with
+ cache_function = (fun (_,obj) -> cache_strategy obj);
+ load_function = (fun _ (_,obj) -> cache_strategy obj);
+ subst_function = subst_strategy;
+ discharge_function = discharge_strategy;
+ classify_function = classify_strategy;
+ export_function = export_strategy }
+
+
+let set_strategy local str =
+ if local then cache_strategy str
+ else Lib.add_anonymous_leaf (inStrategy str)
+
let _ =
Summary.declare_summary "Transparent constants and variables"
{ Summary.freeze_function = Conv_oracle.freeze;
diff --git a/proofs/redexpr.mli b/proofs/redexpr.mli
index 404a8a196..68c1fd669 100644
--- a/proofs/redexpr.mli
+++ b/proofs/redexpr.mli
@@ -26,7 +26,11 @@ val declare_red_expr : string -> reduction_function -> unit
(* Opaque and Transparent commands. *)
-val set_strategy : 'a tableKey -> Conv_oracle.level -> unit
+(* Sets the expansion strategy of a constant. When the boolean is
+ true, the effect is non-synchronous (i.e. it does not survive
+ section and module closure). *)
+val set_strategy :
+ bool -> (Conv_oracle.level * evaluable_global_reference list) list -> unit
(* call by value normalisation function using the virtual machine *)
val cbv_vm : reduction_function
diff --git a/test-suite/complexity/ring2.v b/test-suite/complexity/ring2.v
new file mode 100644
index 000000000..9f9685dde
--- /dev/null
+++ b/test-suite/complexity/ring2.v
@@ -0,0 +1,51 @@
+(* This example, checks the efficiency of the abstract machine used by ring *)
+(* Expected time < 1.00s *)
+
+Require Import BinInt.
+
+Definition Zplus x y :=
+match x with
+| 0%Z => y
+| Zpos x' =>
+ match y with
+ | 0%Z => x
+ | Zpos y' => Zpos (x' + y')
+ | Zneg y' =>
+ match (x' ?= y')%positive Eq with
+ | Eq => 0%Z
+ | Lt => Zneg (y' - x')
+ | Gt => Zpos (x' - y')
+ end
+ end
+| Zneg x' =>
+ match y with
+ | 0%Z => x
+ | Zpos y' =>
+ match (x' ?= y')%positive Eq with
+ | Eq => 0%Z
+ | Lt => Zpos (y' - x')
+ | Gt => Zneg (x' - y')
+ end
+ | Zneg y' => Zneg (x' + y')
+ end
+end.
+
+Require Import Ring.
+
+Lemma Zth : ring_theory Z0 (Zpos xH) Zplus Zmult Zminus Zopp (@eq Z).
+Admitted.
+
+Ltac Zcst t :=
+ match isZcst t with
+ true => t
+ | _ => constr:NotConstant
+ end.
+
+Add Ring Zr : Zth
+ (decidable Zeqb_ok, constants [Zcst]).
+
+Open Scope Z_scope.
+Infix "+" := Zplus : Z_scope.
+
+Goal forall a, a+a+a+a+a+a+a+a+a+a+a+a+a = a*13.
+Time intro; ring.
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
index cf123f584..8c92329e5 100644
--- a/toplevel/vernacentries.ml
+++ b/toplevel/vernacentries.ml
@@ -885,16 +885,15 @@ let _ =
optread=(fun () -> get_debug () <> Tactic_debug.DebugOff);
optwrite=vernac_debug }
-let vernac_set_opacity r =
- let set_one l r =
- let r =
- match global_with_alias r with
- | ConstRef sp -> ConstKey sp
- | VarRef id -> VarKey id
- | _ -> error
- "cannot set an inductive type or a constructor as transparent" in
- set_strategy r l in
- List.iter (fun (l,q) -> List.iter (set_one l) q) r
+let vernac_set_opacity local str =
+ let glob_ref r =
+ match global_with_alias r with
+ | ConstRef sp -> EvalConstRef sp
+ | VarRef id -> EvalVarRef id
+ | _ -> error
+ "cannot set an inductive type or a constructor as transparent" in
+ let str = List.map (fun (lev,ql) -> (lev,List.map glob_ref ql)) str in
+ Redexpr.set_strategy local str
let vernac_set_option key = function
| StringValue s -> set_string_option_value key s
@@ -1269,7 +1268,7 @@ let interp c = match c with
| VernacSyntacticDefinition (id,c,l,b) ->vernac_syntactic_definition id c l b
| VernacDeclareImplicits (local,qid,l) ->vernac_declare_implicits local qid l
| VernacReserve (idl,c) -> vernac_reserve idl c
- | VernacSetOpacity qidl -> vernac_set_opacity qidl
+ | VernacSetOpacity (local,qidl) -> vernac_set_opacity local qidl
| VernacSetOption (key,v) -> vernac_set_option key v
| VernacUnsetOption key -> vernac_unset_option key
| VernacRemoveOption (key,v) -> vernac_remove_option key v
diff --git a/toplevel/vernacexpr.ml b/toplevel/vernacexpr.ml
index fd6beb295..cce6f9a62 100644
--- a/toplevel/vernacexpr.ml
+++ b/toplevel/vernacexpr.ml
@@ -293,7 +293,8 @@ type vernac_expr =
| VernacDeclareImplicits of locality_flag * lreference *
(explicitation * bool * bool) list option
| VernacReserve of lident list * constr_expr
- | VernacSetOpacity of (Conv_oracle.level * lreference list) list
+ | VernacSetOpacity of
+ locality_flag * (Conv_oracle.level * lreference list) list
| VernacUnsetOption of Goptions.option_name
| VernacSetOption of Goptions.option_name * option_value
| VernacAddOption of Goptions.option_name * option_ref_value list