@@ -125,69 +125,71 @@ such that `positivity` successfully recognises both `a` and `b`. -/
125125@ [positivity _ ^ (_ : ℤ), Pow.pow _ (_ : ℤ)]
126126meta def evalZPow : PositivityExt where eval {u α} zα pα? e := do
127127 let .app (.app _ (a : Q($α))) (b : Q(ℤ)) ← withReducible (whnf e) | throwError "not ^"
128- let some pα := pα? |
128+ match (dependent := true ) pα? with
129+ | none =>
129130 match ← core zα pα? a with
130131 | .nonzero pa =>
131132 let _a ← synthInstanceQ q(GroupWithZero $α)
132133 assumeInstancesCommute
133134 haveI ' : $e =Q $a ^ $b := ⟨⟩
134135 pure (.nonzero q(zpow_ne_zero $b $pa))
135136 | _ => pure .none
136- let result ← catchNone do
137- let _a ← synthInstanceQ q(Field $α)
138- let _a ← synthInstanceQ q(LinearOrder $α)
139- let _a ← synthInstanceQ q(IsStrictOrderedRing $α)
140- assumeInstancesCommute
141- match ← whnfR b with
142- | .app (.app (.app (.const `OfNat.ofNat _) _) (.lit (Literal.natVal n))) _ =>
143- guard (n % 2 = 0 )
144- have m : Q(ℕ) := mkRawNatLit (n / 2 )
145- haveI ' : $b =Q $m + $m := ⟨⟩
146- haveI ' : $e =Q $a ^ $b := ⟨⟩
147- pure (.nonnegative q(Even.zpow_nonneg (Even.add_self _) $a))
148- | .app (.app (.app (.const `Neg.neg _) _) _) b' =>
149- let b' ← whnfR b'
150- let .true := b'.isAppOfArity ``OfNat.ofNat 3 | throwError "not a ^ -n where n is a literal"
151- let some n := (b'.getRevArg! 1 ).rawNatLit? | throwError "not a ^ -n where n is a literal"
152- guard (n % 2 = 0 )
153- have m : Q(ℕ) := mkRawNatLit (n / 2 )
154- haveI ' : $b =Q (-$m) + (-$m) := ⟨⟩
155- haveI ' : $e =Q $a ^ $b := ⟨⟩
156- pure (.nonnegative q(Even.zpow_nonneg (Even.add_self _) $a))
157- | _ => throwError "not a ^ n where n is a literal or a negated literal"
158- orElse result do
159- let ra ← core zα pα a
160- let ofNonneg (pa : Q(0 ≤ $a))
161- (_oα : Q(Semifield $α)) (_oα : Q(LinearOrder $α)) (_oα : Q(IsStrictOrderedRing $α)) :
162- MetaM (Strictness zα e pα) := do
163- haveI ' : $e =Q $a ^ $b := ⟨⟩
164- assumeInstancesCommute
165- pure (.nonnegative q(zpow_nonneg $pa $b))
166- let ofNonzero (pa : Q($a ≠ 0 )) (_oα : Q(GroupWithZero $α)) : MetaM (Strictness zα e pα) := do
167- haveI ' : $e =Q $a ^ $b := ⟨⟩
168- let _a ← synthInstanceQ q(GroupWithZero $α)
137+ | some pα =>
138+ let result ← catchNone do
139+ let _a ← synthInstanceQ q(Field $α)
140+ let _a ← synthInstanceQ q(LinearOrder $α)
141+ let _a ← synthInstanceQ q(IsStrictOrderedRing $α)
169142 assumeInstancesCommute
170- pure (.nonzero q(zpow_ne_zero $b $pa))
171- match ra with
172- | .positive pa =>
173- try
174- let _a ← synthInstanceQ q(Semifield $α)
175- let _a ← synthInstanceQ q(LinearOrder $α)
176- let _a ← synthInstanceQ q(IsStrictOrderedRing $α)
143+ match ← whnfR b with
144+ | .app (.app (.app (.const `OfNat.ofNat _) _) (.lit (Literal.natVal n))) _ =>
145+ guard (n % 2 = 0 )
146+ have m : Q(ℕ) := mkRawNatLit (n / 2 )
147+ haveI ' : $b =Q $m + $m := ⟨⟩
148+ haveI ' : $e =Q $a ^ $b := ⟨⟩
149+ pure (.nonnegative q(Even.zpow_nonneg (Even.add_self _) $a))
150+ | .app (.app (.app (.const `Neg.neg _) _) _) b' =>
151+ let b' ← whnfR b'
152+ let .true := b'.isAppOfArity ``OfNat.ofNat 3 | throwError "not a ^ -n where n is a literal"
153+ let some n := (b'.getRevArg! 1 ).rawNatLit? | throwError "not a ^ -n where n is a literal"
154+ guard (n % 2 = 0 )
155+ have m : Q(ℕ) := mkRawNatLit (n / 2 )
156+ haveI ' : $b =Q (-$m) + (-$m) := ⟨⟩
157+ haveI ' : $e =Q $a ^ $b := ⟨⟩
158+ pure (.nonnegative q(Even.zpow_nonneg (Even.add_self _) $a))
159+ | _ => throwError "not a ^ n where n is a literal or a negated literal"
160+ orElse result do
161+ let ra ← core zα pα a
162+ let ofNonneg (pa : Q(0 ≤ $a))
163+ (_oα : Q(Semifield $α)) (_oα : Q(LinearOrder $α)) (_oα : Q(IsStrictOrderedRing $α)) :
164+ MetaM (Strictness zα e pα) := do
165+ haveI ' : $e =Q $a ^ $b := ⟨⟩
177166 assumeInstancesCommute
167+ pure (.nonnegative q(zpow_nonneg $pa $b))
168+ let ofNonzero (pa : Q($a ≠ 0 )) (_oα : Q(GroupWithZero $α)) : MetaM (Strictness zα e pα) := do
178169 haveI ' : $e =Q $a ^ $b := ⟨⟩
179- pure (.positive q(zpow_pos $pa $b))
180- catch e : Exception =>
181- trace[Tactic.positivity.failure] "{ e.toMessageData} "
182- let sα ← synthInstanceQ q(Semifield $α)
183- let oα ← synthInstanceQ q(LinearOrder $α)
184- let iα ← synthInstanceQ q(IsStrictOrderedRing $α)
185- orElse (← catchNone (ofNonneg q(le_of_lt $pa) sα oα iα))
186- (ofNonzero q(ne_of_gt $pa) q(inferInstance))
187- | .nonnegative pa =>
188- ofNonneg pa (← synthInstanceQ (_ : Q(Type u)))
189- (← synthInstanceQ (_ : Q(Type u))) (← synthInstanceQ (_ : Q(Prop )))
190- | .nonzero pa => ofNonzero pa (← synthInstanceQ (_ : Q(Type u)))
191- | .none => pure .none
170+ let _a ← synthInstanceQ q(GroupWithZero $α)
171+ assumeInstancesCommute
172+ pure (.nonzero q(zpow_ne_zero $b $pa))
173+ match ra with
174+ | .positive pa =>
175+ try
176+ let _a ← synthInstanceQ q(Semifield $α)
177+ let _a ← synthInstanceQ q(LinearOrder $α)
178+ let _a ← synthInstanceQ q(IsStrictOrderedRing $α)
179+ assumeInstancesCommute
180+ haveI ' : $e =Q $a ^ $b := ⟨⟩
181+ pure (.positive q(zpow_pos $pa $b))
182+ catch e : Exception =>
183+ trace[Tactic.positivity.failure] "{ e.toMessageData} "
184+ let sα ← synthInstanceQ q(Semifield $α)
185+ let oα ← synthInstanceQ q(LinearOrder $α)
186+ let iα ← synthInstanceQ q(IsStrictOrderedRing $α)
187+ orElse (← catchNone (ofNonneg q(le_of_lt $pa) sα oα iα))
188+ (ofNonzero q(ne_of_gt $pa) q(inferInstance))
189+ | .nonnegative pa =>
190+ ofNonneg pa (← synthInstanceQ (_ : Q(Type u)))
191+ (← synthInstanceQ (_ : Q(Type u))) (← synthInstanceQ (_ : Q(Prop )))
192+ | .nonzero pa => ofNonzero pa (← synthInstanceQ (_ : Q(Type u)))
193+ | .none => pure .none
192194
193195end Mathlib.Meta.Positivity
0 commit comments