Hello, I have a code which hangs for so long on rewrite tactic.
I profiled it, it turns out rewrite
in ssreflect cannot be broken down into inner invocations.
total time: 69.352s
tactic local total calls max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─rewrite (ssrrwargs) (ssrclauses) ------ 100.0% 100.0% 1 69.352s
tactic local total calls max
────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
─rewrite (ssrrwargs) (ssrclauses) ------ 100.0% 100.0% 1 69.352s
It runs for so long, but it is not infinite loop - it stops at 69.352s.
Let's say this is rewrite fooE
.
Funny thing is, rewrite {1}fooE
terminates instantly. rewrite {2}fooE
runs indefinitely long, though.
What is the possible cause of this? How do I debug this problem? I do not even know where to look for.
Thanks in advance!
Can we have a concrete piece of code where rewrite takes time?
Oh right, this topic should be in #math-comp analysis . Sorry..
Basically, I have this setup for bounded operators.
Then, I define frechet differential in different file :
From mathcomp Require Import all_ssreflect.
From mathcomp Require Import ssralg ssrnum matrix.
From mathcomp Require Import boolp reals classical_sets signed topology functions.
From mathcomp Require Import prodnormedzmodule normedtype landau forms derive.
From mathcomp Require Import ring.
From manifolds Require Import lineartopo.
Set Implicit Arguments.
Import GRing.Theory.
Import numFieldNormedType.Exports.
Local Open Scope classical_set_scope.
Local Open Scope ring_scope.
Section FrechetDiff.
Context (R: realType) (U V: normedModType R).
Definition frechet_diff (f : U -> V) x : {bounded U -> V} :=
xget 0 [set df : {bounded U -> V} | 'd f x = df].
Definition fdiffble (f: U -> V) := forall x, differentiable f x.
End FrechetDiff.
Arguments fdiffble {R} {U V} f.
Notation "''D' f" := (@frechet_diff _ _ _ f) (at level 100, f at level 0).
Lemma frechet_diffE (R: realType) (U V: normedModType R) (f : U -> V) x :
differentiable f x -> 'D f x = 'd f x :> {linear U -> V}.
Proof.
move=> Hf. have HC : linear_conti ('d f x).
- rewrite in_setE /=. by have := diff_continuous Hf.
pose df := BddLinear HC.
rewrite /frechet_diff (@xget_subset1 _ 0 _ df) //.
move=> da db /= ->. apply/val_inj.
Qed.
Section FrechetProps.
Context (R: realType) (U V W: normedModType R).
Implicit Types (f g : U -> V).
Lemma frechet_diff_cst c : 'D (cst c) = 0 :> (U -> {bounded U -> V}).
Proof.
apply/funext=> x. apply/val_inj=> /=.
rewrite frechet_diffE; last by apply/differentiable_cst.
apply/linear_eq/diff_cst.
Qed.
Lemma frechet_diffD f g : fdiffble f -> fdiffble g ->
'D (f + g) = 'D f + 'D g.
Proof.
move=> Hf Hg. apply/funext=> x. apply/val_inj=> /=.
rewrite frechet_diffE.
The last line, rewrite frechet_diffE
, takes tens of seconds to execute.
A message was moved here from #math-comp users > Rewriting takes long time, how to debug? by Karl Palmskog.
abab9579 has marked this topic as resolved.
(Moved to math-comp analysis)
better to move the whole thing, I think
Karl Palmskog has marked this topic as unresolved.
This topic was moved here from #math-comp users > Rewriting takes long time, how to debug? by Karl Palmskog.
Just a wild guess: the following means that, in order to rewrite frechet_diffE
, rewrite has to find a linear structure on something somewhere in the goal, which can be difficult.
Lemma frechet_diffE (R: realType) (U V: normedModType R) (f : U -> V) x :
differentiable f x -> 'D f x = 'd f x :> {linear U -> V}.
To better see this, you can
Set Printing All.
Check frechet_difE
Wow, it gives huge type.
frechet_diffE
: forall (R : Real.type)
(U
V : @NormedModule.type (Real.numDomainType R) (Phant (Real.sort R)))
(f : forall
_ : @NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) U,
@NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) V)
(x : @Filtered.sort
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)
(Topological.filteredType
(@NormedModule.topologicalType
(Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)))
(_ : @differentiable_def (Real.numDomainType R) U V f
(@nbhs_filter_on
(@NormedModule.topologicalType
(Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)
x)
(Phantom
(set
(set
(@NormedModule.sort (Real.numDomainType R)
(Phant
(Num.NumDomain.sort (Real.numDomainType R))) U)))
(@filter_of
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R)))
U)
(Topological.filteredType
(@NormedModule.topologicalType
(Real.numDomainType R)
(Phant
(Num.NumDomain.sort (Real.numDomainType R))) U))
x
(Phantom
(@Filtered.sort
(@NormedModule.sort (Real.numDomainType R)
(Phant
(Num.NumDomain.sort (Real.numDomainType R)))
U)
(Topological.filteredType
(@NormedModule.topologicalType
(Real.numDomainType R)
(Phant
(Num.NumDomain.sort
(Real.numDomainType R))) U))) x)))),
@eq
(@GRing.Linear.map (Num.NumDomain.ringType (Real.numDomainType R))
(@NormedModule.lmodType (Real.numDomainType R)
(Phant
(GRing.Ring.sort
(Num.NumDomain.ringType (Real.numDomainType R)))) U)
(@GRing.Lmodule.zmodType
(Num.NumDomain.ringType (Real.numDomainType R))
(Phant
(GRing.Ring.sort
(Num.NumDomain.ringType (Real.numDomainType R))))
(@NormedModule.lmodType (Real.numDomainType R)
(Phant
(GRing.Ring.sort
(Num.NumDomain.ringType (Real.numDomainType R)))) V))
(@GRing.scale (Num.NumDomain.ringType (Real.numDomainType R))
(@NormedModule.lmodType (Real.numDomainType R)
(Phant
(GRing.Ring.sort
(Num.NumDomain.ringType (Real.numDomainType R)))) V))
(Phant
(forall
_ : @NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) U,
@NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) V)))
(@bdval R U V
(Phant
(forall
_ : @NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) U,
@NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) V)) (@frechet_diff R U V f x))
(@diff (Real.numDomainType R) U V
(@nbhs_filter_on
(@NormedModule.topologicalType (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U) x)
(Phantom
(set
(set
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)))
(@filter_of
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)
(Topological.filteredType
(@NormedModule.topologicalType
(Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U))
x
(Phantom
(@Filtered.sort
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R)))
U)
(Topological.filteredType
(@NormedModule.topologicalType
(Real.numDomainType R)
(Phant
(Num.NumDomain.sort (Real.numDomainType R)))
U))) x))) f)
I don't see finding linear structure part though.
the "huge" part is due to this, but it's at least better than this
The equality is on Linear, the left hand side has bdval
at its head, I guess, this came from unfolding frechet_diff
. Maybe locking frechet_diff
could help.
This does not improve the performance:
Definition frechet_diff (f : U -> V) x : {bounded U -> V} :=
locked xget 0 [set df : {bounded U -> V} | 'd f x = df].
Where should I lock instead?
What about?
Definition frechet_diff (f : U -> V) x : {bounded U -> V} :=
locked (xget 0 [set df : {bounded U -> V} | 'd f x = df]).
Definition frechet_diff (f : U -> V) x : {bounded U -> V} :=
locked (xget 0 [set df : {bounded U -> V} | 'd f x = df]).
Problem still persists with this ^
The type is still this:
frechet_diff : forall (R : Real.type)
(U V : @NormedModule.type (Real.numDomainType R) (Phant (Real.sort R)))
(f : forall
_ : @NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) U,
@NormedModule.sort (Real.numDomainType R) (Phant (Real.sort R)) V)
(x : @Filtered.sort
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)
(Topological.filteredType
(@NormedModule.topologicalType (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)))
(_ : @differentiable_def (Real.numDomainType R) U V f
(@nbhs_filter_on
(@NormedModule.topologicalType (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U) x)
(Phantom
(set
(set
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R)))
U)))
(@filter_of
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)
(Topological.filteredType
(@NormedModule.topologicalType
(Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R)))
U)) x
(Phantom
(@Filtered.sort
(@NormedModule.sort (Real.numDomainType R)
(Phant
(Num.NumDomain.sort (Real.numDomainType R))) U)
(Topological.filteredType
(@NormedModule.topologicalType
(Real.numDomainType R)
(Phant
(Num.NumDomain.sort (Real.numDomainType R)))
U))) x)))),
@eq
(@GRing.Linear.map (Num.NumDomain.ringType (Real.numDomainType R))
(@NormedModule.lmodType (Real.numDomainType R)
(Phant
(GRing.Ring.sort
(Num.NumDomain.ringType (Real.numDomainType R)))) U)
(@GRing.Lmodule.zmodType
(Num.NumDomain.ringType (Real.numDomainType R))
(Phant
(GRing.Ring.sort
(Num.NumDomain.ringType (Real.numDomainType R))))
(@NormedModule.lmodType (Real.numDomainType R)
(Phant
(GRing.Ring.sort
(Num.NumDomain.ringType (Real.numDomainType R)))) V))
(@GRing.scale (Num.NumDomain.ringType (Real.numDomainType R))
(@NormedModule.lmodType (Real.numDomainType R)
(Phant
(GRing.Ring.sort
(Num.NumDomain.ringType (Real.numDomainType R)))) V))
(Phant
(forall
_ : @NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) U,
@NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) V)))
(@bdval R U V
(Phant
(forall
_ : @NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) U,
@NormedModule.sort (Real.numDomainType R)
(Phant (Real.sort R)) V)) (@frechet_diff R U V f x))
(@diff (Real.numDomainType R) U V
(@nbhs_filter_on
(@NormedModule.topologicalType (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U) x)
(Phantom
(set
(set
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)))
(@filter_of
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)
(Topological.filteredType
(@NormedModule.topologicalType (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U))
x
(Phantom
(@Filtered.sort
(@NormedModule.sort (Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R))) U)
(Topological.filteredType
(@NormedModule.topologicalType
(Real.numDomainType R)
(Phant (Num.NumDomain.sort (Real.numDomainType R)))
U))) x))) f)
Ok, the problem is probably not the fact that rewrite unfolds frechet_diff
but rather probably the fact that you have this bdval
(don't know what it is) around frechet diff
. If you don't have it in you goal, that could explain why rewrite is in trouble.
Can't you replace :> {linear U -> V}
by :> {bounded U -> V}
(the type of frechet_diff
) in frechet_diffE
?
No, this is impossible. 'd f x : {linear U -> V}
, and {bounded U -> V}
is subtype of it, there is no way to automatically get the latter from former.
After apply/funext=> x. apply/val_inj=> /=.
, the equation effectively becomes
bdval ('D (f + g) x) = bdval ('D f x) + bdval ('D g x)
So there is definitely bdval
.
The setup of {bounded U -> V}
and bdval
is here: https://gist.github.com/Abastro/036f5c410dae630106dd75440746887b
Ok, thanks for the explanation, then I'm afraid you have no other choice than Set Printing All
and inspect the goal and frechet_diffE
to pinpoint the difference.
Oh. So.. should I look into the unfolded terms and compare them?
If you think they should be the same, yes.
If you have both bdval
and frechet_diff
in both the lemma and the goal, then the difference likely lies in the other arguments (of bdval
or grechet_diff
)
Last updated: Sep 28 2023 at 11:01 UTC