Zulip Chat Archive
Stream: general
Topic: Structure substitution
Alice Laroche (Aug 17 2021 at 22:05):
Is there a way to go from this context :
prop: Point → Prop
⊢ prop {x := 0, y := 0}
to this one :
prop: Point → Prop
p: Point := {x := 0, y := 0}
⊢ prop p
Yakov Pechersky (Aug 17 2021 at 22:16):
let p : Point := {x := 0, y := 0}
Alice Laroche (Aug 17 2021 at 22:27):
Naaah, It's giving me the object in the context but it doesn't replace it in the goal.
Eric Rodriguez (Aug 17 2021 at 22:28):
you can use change ...
or set ... with hp, rw ←hp at *
to force it to behave
Eric Rodriguez (Aug 17 2021 at 22:28):
and worst case they are defeq so you can mostly just pretend that it's fine
Floris van Doorn (Aug 17 2021 at 22:51):
import tactic.interactive
example {α} (p : α → Prop) (x : α) : p x :=
begin
set y := x,
/- State
α : Sort ?,
p : α → Prop,
x : α,
y : α := x
⊢ p y
-/
end
Floris van Doorn (Aug 17 2021 at 22:53):
@Yakov Pechersky was off by 1 letter :)
Yakov Pechersky (Aug 17 2021 at 22:54):
is there a reason we still have let
as opposed to set
? because let
is in core?
Eric Rodriguez (Aug 17 2021 at 22:54):
set
can sometimes still not overwrite though, and let
is slightly different with binders iirc
Floris van Doorn (Aug 17 2021 at 22:56):
let
seems also useful, if you don't want to change the other hypotheses or the goal. But in cases where they behave differently, you usually want to use set
.
Alice Laroche (Aug 17 2021 at 22:58):
Huuuu,
For strange reason, it's not working in my actual proof, but it work with a not-sso-working mwe
Floris van Doorn (Aug 17 2021 at 23:00):
Ideas:
- Does Eric's suggestion with
rw ←hp at *
help? - Double check that the value of
p
and the term in the goal are precisely the same, including in implicit arguments etc. (Maybe you can click through them in widgets?).
Alice Laroche (Aug 17 2021 at 23:02):
"MWE"
example (prop : Point → Prop) : prop (create_point 0 0) :=
begin
let p : Point := create_point 0 0,
change create_point 0 0 with p,
/- State
prop: Point → Prop
p: Point := create_point 0 0
⊢ prop p
-/
end
Actual proof :
theorem rename_accept (fsa : FSA S L) (old new : S) (h₁ : new ∉ fsa.states) (w : word L) : accept fsa w → accept (rename_state fsa old new h₁) w :=
begin
intro h₂,
let fsa' : FSA S L := rename_state fsa old new h₁,
change rename_state fsa old new h₁ with fsa',
/- State
...
fsa': FSA S L := fsa.rename_state old new h₁
⊢ (fsa.rename_state old new h₁).accept w
-/
end
Floris van Doorn (Aug 17 2021 at 23:05):
did you try set
?
If you replace the let
by set fsa' : FSA S L := rename_state fsa old new h₁ with hp
does rw ←hp
or simp_rw ←hp
do anything?
Floris van Doorn (Aug 17 2021 at 23:07):
Does change fsa'.accept w
work after your let
?
Alice Laroche (Aug 17 2021 at 23:07):
Well it's work but i don't understand why change doesn't work in the same way
Alice Laroche (Aug 17 2021 at 23:07):
(set + rw hp)
Alice Laroche (Aug 17 2021 at 23:08):
And change fsa'.accept w work too
Very strange
Alice Laroche (Aug 18 2021 at 12:56):
In the same topic, is there a way to rewrite the definition of a structure ?
like go from p: Point := {x := 0, y := 1 + 1}
to p: Point := {x := 0, y := 2}
for example
Yaël Dillies (Aug 18 2021 at 13:08):
You can prove the equality between those two using ext
, and then use that to rw
. Maybe there's a shortcut, though. Like, in that particular instance, your two points are defeq.
Eric Wieser (Aug 18 2021 at 13:18):
Can you give a #mwe?
Alice Laroche (Aug 18 2021 at 15:00):
Yaël Dillies
If i do :
example : true :=
begin
let p : Point := { x := 0, y := 1 + 1 },
have h : {Point . x := 0, y := 1 + 1} = {Point . x := 0, y := 2} := rfl,
rw h at p,
end
I obtain
/- State
rewrite tactic failed, did not find instance of the pattern in the target expression
{x := 0, y := 1 + 1}
state:
p : Point := {x := 0, y := 1 + 1},
h : {x := 0, y := 1 + 1} = {x := 0, y := 2}
-/
⊢ true
Yakov Pechersky (Aug 18 2021 at 15:04):
p is not a hypothesis at which you can rewrite. Use "set p :=... with hp"
Alice Laroche (Aug 18 2021 at 15:22):
Hmmm, of course it's work but it doesn't help me to do what i hoped to do
I have
example : ∃x, some_prop x :=
begin
let x : Big_struct := func_which_eval_into_a_really_big_struct,
use x,
end
But now to prove the goal i need to access to the value of the fields of the structure, but i can't because i_eval_into_a_really_big_struct
is not unfolded
I can use set p :=... with hp
and unfold it in hp then rewrite x in the goal , but then i have a big structure in the goal and it's messy and unreadable
Yakov Pechersky (Aug 18 2021 at 15:44):
Very hard to understand your issue without a mwe context. Why not just "use (func_which_eval)"?
Alice Laroche (Aug 18 2021 at 16:10):
Hmmm,
I guess this work ? I hope you will understand my mindset
import tactic
structure Big_struct :=
(a : ℕ)
(b : ℕ)
(c : Prop)
(d : Prop)
(e : Prop)
(f : Prop)
(g : Prop)
(h : Prop)
(i : Prop)
(j : Prop)
(k : Prop)
(l : Prop)
(m : Prop)
@[simp] def i_eval_to_big_struct (a b : ℕ): Big_struct :=
{
a := a,
b := b,
c := true,
d := true,
e := true,
f := true,
g := true,
h := true,
i := true,
j := true,
k := true,
l := true,
m := true,
}
-- work but ugly
example (f : Big_struct → Big_struct) : ∃x : Big_struct, x.a > (f x).b :=
begin
use (i_eval_to_big_struct 5 2),
/- State
f: Big_struct → Big_struct
⊢ (i_eval_to_big_struct 5 2).a > (f (i_eval_to_big_struct 5 2)).b
-/
simp,
/- State
f: Big_struct → Big_struct
⊢ (f {a := 5, b := 2, c := true, d := true, e := true, f := true, g := true, h := true, i := true, j := true, k := true, l := true, m := true}).b < 5
-/
end
-- what i wish i could do
example (f : Big_struct → Big_struct) : ∃x : Big_struct, x.a > (f x).b :=
begin
some_tactics,
/-
f: Big_struct → Big_struct
x: Big_struct := {a := 5, b := 2, c := true, d := true, e := true, f := true, g := true, h := true, i := true, j := true, k := true, l := true, m := true}
⊢ x.a > (f x).b
-/
simp,
/- State
f: Big_struct → Big_struct
x: Big_struct := {a := 5, b := 2, c := true, d := true, e := true, f := true, g := true, h := true, i := true, j := true, k := true, l := true, m := true}
⊢ (f x).b < 5
-/
end
Floris van Doorn (Aug 18 2021 at 17:26):
Here are two options to do roughly want you want
-- to get mostly what you want
example (f : Big_struct → Big_struct) : ∃x : Big_struct, x.a > (f x).b :=
begin
let x := i_eval_to_big_struct 5 2,
use x,
/-
f: Big_struct → Big_struct
x: Big_struct := i_eval_to_big_struct 5 2
⊢ x.a > (f x).b
-/
revert x, dsimp [i_eval_to_big_struct, gt] {zeta := ff}, intro x,
/- State
f: Big_struct → Big_struct
x: Big_struct := {a := 5, b := 2, c := true, d := true, e := true, f := true, g := true, h := true, i := true, j := true, k := true, l := true, m := true}
⊢ (f x).b < 5
-/
end
-- another option
example (f : Big_struct → Big_struct) : ∃x : Big_struct, x.a > (f x).b :=
begin
generalize hx : i_eval_to_big_struct 5 2 = x,
use x,
/-
f: Big_struct → Big_struct
x: Big_struct
hx: i_eval_to_big_struct 5 2 = x
⊢ x.a > (f x).b
-/
conv_lhs { rw [←hx] }, simp [i_eval_to_big_struct],
/- State
f: Big_struct → Big_struct
x: Big_struct
hx: i_eval_to_big_struct 5 2 = x
⊢ (f x).b < 5
-/
end
Kyle Miller (Aug 18 2021 at 17:36):
For others who, like me, aren't familiar with fancy options to dsimp
, this is what zeta
is for:
(zeta : bool := tt) -- do zeta-reductions: `let x : a := b in c ↝ c[x/b]`.
Last updated: Dec 20 2023 at 11:08 UTC