Zulip Chat Archive

Stream: metaprogramming / tactics

Topic: Making a tactic more efficient


Andre Hernandez-Espiet (Rutgers) (Sep 26 2022 at 19:20):

Hi all, I wrote the following tactics:

import data.real.basic
universes u1 u2
class incidence_geometry :=
(point : Type u1)
(line : Type u2)
(online : point  line  Prop)
(sameside : point  point  line  Prop)
(not_online_of_sameside :  {a b : point},  {L : line}, sameside a b L  ¬online a L)

open incidence_geometry

instance incidence_geometry_ℝ_ℝ : incidence_geometry :=
{ point :=  × , -- p = (x, y)
  line :=  ×  × , -- a x + b y = c ↔ (a, b, c)
  online := sorry,
  sameside := sorry,
  not_online_of_sameside := sorry,
   }

variables[i: incidence_geometry]

theorem neq_of_online_offline {a b : point} {L : line} (aL : online a L) (bL : ¬online b L) : a  b :=
begin
  intro ab, rw ab at aL, exact bL aL,
end

theorem side {a b c: point} {L: line} (bL: online b L) (acL: sameside a c L) : a b
:=(neq_of_online_offline bL (not_online_of_sameside acL)).symm

meta def exact_list : list expr   tactic unit
| [] := tactic.fail "no matching expression found"
| (h :: hs) :=
do {
tactic.applyc ``neq_of_online_offline,
tactic.exact h,
tactic.assumption
}
<|> exact_list hs

meta def exact_list2 : list expr   tactic unit
| [] := tactic.fail "no matching expression found"
| (h :: hs) :=
do {
tactic.applyc ``side,
tactic.exact h,
tactic.assumption
}
<|> exact_list2 hs

meta def neq: tactic unit :=
do
hs   tactic.local_context,
(exact_list hs <|> exact_list2 hs)

theorem neqtest {a b c: point} {L: line} (bL: online b L) (acL: sameside a c L)  : a  b :=
begin
  neq,
end

theorem neqtest2 {a b : point } {L: line} (aL: online a L) (bL: ¬ online b L) : a b :=by neq

Basically, I made a tactic that tries the theorems side and neq_of_online_offline consecutively. However, I had to write exact_list2 in addition to exact_list in order to try both theorems. I feel like I'm missing an easy way to try as many theorems as I want with just two meta programs. Is there a way to make this work more efficiently?

Heather Macbeth (Sep 26 2022 at 19:21):

Have you looked at tactic#apply_rules ?

Heather Macbeth (Sep 26 2022 at 19:59):

@Andre Hernandez-Espiet (Rutgers) I looked a little more at your use case and it seems like you need to backtrack, not just apply the first lemma that fits. So you want the generalization tactic#solve_by_elim of apply_rules. Here:

import tactic

class incidence_geometry :=
(point : Type*)
(line : Type*)
(online : point  line  Prop)
(sameside : point  point  line  Prop)
(not_online_of_sameside :  {a b : point},  {L : line}, sameside a b L  ¬online a L)

export incidence_geometry (online sameside not_online_of_sameside)

variables [i : incidence_geometry] {a b c : i.point} {L : i.line}

theorem neq_of_online_offline (aL : online a L) (bL : ¬online b L) :   a  b :=
begin
  intro ab, rw ab at aL, exact bL aL,
end

theorem side (bL: online b L) (acL: sameside a c L) : a  b :=
(neq_of_online_offline bL (not_online_of_sameside acL)).symm

/-- Tactic for deducing disequalities among points. -/
meta def neq : tactic unit := `[solve_by_elim [neq_of_online_offline, side]]

example (bL: online b L) (acL: sameside a c L) : a  b := by neq

example (aL: online a L) (bL: ¬ online b L) : a  b := by neq

Heather Macbeth (Sep 26 2022 at 20:00):

(Note: work on asking questions with #mwe -- everything in your question involving the reals was irrelevant.)

Heather Macbeth (Sep 26 2022 at 20:12):

In practice, you probably want something extensible, to which you can add more relevant lemmas as they accumulate. You can do this using the solve_by_elim option which brings in all lemmas marked with a certain attribute:

@[user_attribute]
meta def point_neq : user_attribute :=
{ name := `point_neq,
  descr := "lemmas usable to prove disequalities of points" }

/-- Tactic for deducing disequalities among points. -/
meta def neq : tactic unit := `[solve_by_elim with point_neq]

Heather Macbeth (Sep 26 2022 at 20:13):

Now tag each relevant lemma with @[point_neq] as you prove it.

@[point_neq] theorem side (bL: online b L) (acL: sameside a c L) : a  b :=
(neq_of_online_offline bL (not_online_of_sameside acL)).symm

Notification Bot (Sep 26 2022 at 23:00):

Andre Hernandez-Espiet (Rutgers) has marked this topic as unresolved.

Andre Hernandez-Espiet (Rutgers) (Sep 26 2022 at 23:01):

I am going more with the Euclidean side. Working with Euclid's elements.

Andre Hernandez-Espiet (Rutgers) (Sep 26 2022 at 23:03):

Also, I feel like I'm missing something very silly. Why doesn't the example get proven by neq?

import tactic

class incidence_geometry :=
(point : Type*)
(line : Type*)
(online : point  line  Prop)
(B : point  point  point  Prop) -- Betweenness
(online_2_of_B :  {a b c : point},  {L : line}, B a b c  online a L  online c L  online b L)

export incidence_geometry (online B online_2_of_B)

variables [i : incidence_geometry] {a b c d: i.point} {L : i.line}

@[user_attribute]
meta def point_neq : user_attribute :=
{ name := `point_neq,
  descr := "lemmas usable to prove disequalities of points" }

meta def neq : tactic unit := `[solve_by_elim with point_neq]

@[point_neq] theorem neq_of_online_offline (aL : online a L) (bL : ¬online b L) :   a  b :=
begin
  intro ab, rw ab at aL, exact bL aL,
end

@[point_neq] theorem bet_nq (aL: online a L) (bL: online b L) (cL: ¬ online c L) (Bet: B a d b) : c d :=
(neq_of_online_offline (online_2_of_B Bet aL bL) cL).symm

example (aL: online a L) (bL: online b L) (cL: ¬ online c L) (Bet: B a d b) : c d := by neq

Heather Macbeth (Sep 26 2022 at 23:46):

@Andre Hernandez-Espiet (Rutgers) Increasing the "max depth" seems to work:

meta def neq : tactic unit := `[solve_by_elim with point_neq { max_depth := 5 }]

Andre Hernandez-Espiet (Rutgers) (Sep 27 2022 at 02:04):

For this small example this works. However, for my longer code I then get the error excessive memory consumption detected at 'expression equality test' (potential solution: increase memory consumption threshold) Any ideas on how to increase the threshold?

Andre Hernandez-Espiet (Rutgers) (Sep 27 2022 at 16:33):

I went to vscode's settings and changed the memory limit from 2GB to 12GB and it still gives the same issue, so this doesn't seem to be it...

Heather Macbeth (Sep 28 2022 at 13:47):

@Andre Hernandez-Espiet (Rutgers) Maybe something is looping ... I don't know but in any case I don't think it's a metaprogramming-specific issue; you could isolate it and ask on #general.


Last updated: Dec 20 2023 at 11:08 UTC