Zulip Chat Archive

Stream: general

Topic: segfault


Rob Lewis (Aug 10 2018 at 15:16):

I just managed to crash Lean, and realized it's been quite a while since the last time!

import tactic.wlog

example (x y : ) : x  y :=
begin
  wlog : x  y using [x x],
end

Rob Lewis (Aug 10 2018 at 15:16):

@Johannes Hölzl This isn't really your problem in the end, but maybe it's possible to work around in wlog?

Kevin Buzzard (Aug 10 2018 at 15:22):

Oh nice! I absolutely agree -- Lean has been super-stable since they fixed some memory leak several months ago, it's been a joy to use. I do get the occasional segfault, almost always because my input file is garbage (e.g. I'm deleting hundreds of lines of a file and Lean just started to read a file which starts in the middle of a proof, or possibly even the middle of a word), and furthermore I've never been able to reproduce. It's very rare to get a reproducible segfault nowadays. I can reproduce here BTW.

Mario Carneiro (Aug 10 2018 at 16:26):

Found it

open tactic
example (x : ℕ) : true :=
by do x ← get_local `x, revert_lst [x, x]

Mario Carneiro (Aug 10 2018 at 16:27):

don't revert the same variable twice, I guess

Kevin Buzzard (Aug 10 2018 at 16:27):

I remember my mother telling me that as a child

Mario Carneiro (Aug 10 2018 at 16:27):

note that using revert x twice causes a regular error in the second call

Kevin Buzzard (Aug 10 2018 at 16:29):

revert_lst has no docstring :-(

Mario Carneiro (Aug 10 2018 at 16:29):

presumably it reverts a list

Kevin Buzzard (Aug 10 2018 at 16:31):

or a lst

Simon Hudon (Aug 10 2018 at 19:35):

don't revert the same variable twice, I guess

I'll do what I want!

Kevin Buzzard (Sep 06 2018 at 19:18):

another wloggy segfault:

import tactic.wlog

example (m n : ): false :=
begin
  wlog h : n + n  m + m, -- segv
end

(as you can guess this is the first time I used wlog, I was just trying things out)

Simon Hudon (Sep 06 2018 at 19:19):

Dang! I don't remember putting segfault as one of the features

Simon Hudon (Sep 06 2018 at 19:20):

Can you edit the mathlib sources?

Mario Carneiro (Sep 06 2018 at 19:40):

fixed

Simon Hudon (Sep 06 2018 at 19:40):

What was the issue?

Mario Carneiro (Sep 06 2018 at 19:41):

it triggered the x <= y special case and assumed n + n was a variable

Mario Carneiro (Sep 06 2018 at 19:41):

I am not sure what happened after that, but possibly this got passed into revert

Mario Carneiro (Sep 06 2018 at 19:42):

that's what caused the last segfault, at least

Simon Hudon (Sep 06 2018 at 19:42):

I see. That was not a source of segfault I thought of

Simon Hudon (Sep 06 2018 at 19:42):

Did you add Kevin's example to the test suite?

Mario Carneiro (Sep 06 2018 at 19:43):

I think wlog parsing is currently way too complicated. It should be broken up and documented

Simon Hudon (Sep 06 2018 at 19:43):

That makes sense, I really don't understand the tactic anymore.

Mario Carneiro (Sep 06 2018 at 19:46):

This test fails now:

example {x y z : ℕ} : true :=
begin
  suffices : false, trivial,
  wlog h : x ≤ y + z,
  { guard_target x ≤ y + z ∨ x ≤ z + y,
    admit },
  { guard_hyp h := x ≤ y + z,
    guard_target false,
    admit }
end

what the heck is this supposed to do?

Simon Hudon (Sep 06 2018 at 19:47):

Can you show the state right after wlog?

Mario Carneiro (Sep 06 2018 at 19:47):

it fails

Mario Carneiro (Sep 06 2018 at 19:48):

the error is To generate cases at least two permutations are required, i.e. `using [x y, y x]` or exactly 0 or 2 variables but the problem is that the given pattern x ≤ y + z has 3 variables

Simon Hudon (Sep 06 2018 at 19:48):

It tries to prove false just to make sure that no call to trivial or assumption finishes the goal before we can see the result

Simon Hudon (Sep 06 2018 at 19:49):

Ah I see. That's from when we only considered two variables

Simon Hudon (Sep 06 2018 at 19:49):

It guessed x and y.

Mario Carneiro (Sep 06 2018 at 19:50):

My question is, what is this supposed to do in the first place? It used to just take the last two variables and permute them, as you can see from the asserted target

Simon Hudon (Sep 06 2018 at 19:50):

I'm surprised it hasn't failed before

Mario Carneiro (Sep 06 2018 at 19:50):

It was previously just matching the list of variables against (x :: y :: _) i.e. >= 2 vars, take the first 2

Mario Carneiro (Sep 06 2018 at 19:51):

I changed this to [x, y] and now this test fails

Simon Hudon (Sep 06 2018 at 19:51):

Why are you changing it to [x,y]?

Simon Hudon (Sep 06 2018 at 19:53):

You were the one suggesting we guess the last two variables of the pattern.

Mario Carneiro (Sep 06 2018 at 19:53):

No, that's what it was doing before I touched it

Mario Carneiro (Sep 06 2018 at 19:54):

I don't understand why the code is written that way, but there is a test asserting this behavior

Simon Hudon (Sep 06 2018 at 19:56):

I'm looking at master right now and what I see is (x :: y :: _), not [x, y]

Mario Carneiro (Sep 06 2018 at 20:05):

https://github.com/leanprover/mathlib/blob/master/tactic/wlog.lean#L203

Simon Hudon (Sep 06 2018 at 20:12):

My mistake, I must have done something wrong

Simon Hudon (Sep 06 2018 at 20:12):

What happens if you switch it back to (x :: y :: _)?

Mario Carneiro (Sep 06 2018 at 20:14):

then it works, although the behavior in that case is peculiar

Mario Carneiro (Sep 06 2018 at 20:15):

it just permutes the last two variables discovered in the term, which is a bit weirdly nondeterministic

Simon Hudon (Sep 06 2018 at 20:17):

What would you expect it to do in this case?

Mario Carneiro (Sep 06 2018 at 20:19):

fail, or do all permutations of the n variables

Johan Commelin (Sep 06 2018 at 20:20):

permutations are now in mathlib. Does that help?

Johan Commelin (Sep 06 2018 at 20:21):

Ooh, wait. They were already for a long time... it is the signs that are new.

Mario Carneiro (Sep 06 2018 at 20:21):

we already had list.permutations

Simon Hudon (Sep 06 2018 at 20:24):

I'm not sure if you recall but we have had that conversation before. You were in favor of guessing the variables, I was in favor of requiring that the user specify them

Mario Carneiro (Sep 06 2018 at 20:25):

Actually both options are available here

Mario Carneiro (Sep 06 2018 at 20:28):

honestly I have no idea why it's so complicated. 2 variables seems to be special cased in the parsing, so wlog h : x ≤ y + z using x y z just fails (previously it would just permute x and y)

Mario Carneiro (Sep 06 2018 at 20:29):

Part of the problem is that I don't know the specification of the tactic, and the code is so ad hoc it's hard to tell what is intended and what is accident

Simon Hudon (Sep 06 2018 at 20:35):

It's probably that I started it intending to support only two variables and @Johannes Hölzl probably didn't want to disturb too much

Simon Hudon (Sep 06 2018 at 20:35):

Do you want to settle on a specification now?

Mario Carneiro (Sep 06 2018 at 20:36):

I'm trying to get one out of the docstring now

Mario Carneiro (Sep 06 2018 at 20:43):

There are I guess 24 combinations resulting from the parse:

wlog h? (: pat)? (:= r)? (using x y z)?
wlog h? (: pat)? (:= r)? (using [x y z, z y x])?
  • h is just a name. If it is omitted, the default name is case (Although from the code it looks like if r is the name of a local constant then it is renamed to h?)

Mario Carneiro (Sep 06 2018 at 20:46):

  • If pat and r are both omitted there is an error
  • If pat is given but not r it becomes a subgoal
  • If r is given but not pat it is reconstructed as the first disjunct of r's type

Mario Carneiro (Sep 06 2018 at 20:49):

  • If using list is omitted it is inferred as the set of distinct variables in pat
  • If using is a list of variables then all permutations of those variables are considered
  • If using is a nonempty list of permutations then the first permutation is considered as the list of variables (and the rest must actually be permutations)
  • If using is an empty list of permutations it is treated as omitted

Mario Carneiro (Sep 06 2018 at 20:52):

Oh, I think this is the justification for the last two variables thing:

(4) `wlog : R x y using x y` and `wlog : R x y`
  Produces the case `R x y ∨ R y x`. If `R` is ≤, then the disjunction discharged using linearity.
  If `using x y` is avoided then `x` and `y` are the last two variables appearing in the
  expression `R x y`. -/

Simon Hudon (Sep 06 2018 at 20:53):

Yes, I think that was the entirety of the docstring before Johannes worked on wlog

Mario Carneiro (Sep 06 2018 at 20:54):

I guess this is to allow for when the relation is itself parameterized in some variables

Mario Carneiro (Sep 06 2018 at 20:54):

I wonder whether we can use type information to eliminate some permutations

Simon Hudon (Sep 06 2018 at 20:54):

I think we can map those notations to a set of core parameters. Sometimes they are specified by the user, sometimes they have to be guessed. Working from there, we should say how they are guessed and what is done with those core parameters.

Mario Carneiro (Sep 06 2018 at 20:55):

There is already a notion of core parameters, I think, which are used in tactic.wlog (noninteractive)

Simon Hudon (Sep 06 2018 at 20:55):

Ah good so now we're only struggling with parsing / guessing

Simon Hudon (Sep 06 2018 at 20:56):

Actually R x y was just a way of writing x ≤ y while not involving a specific relation.

Mario Carneiro (Sep 06 2018 at 20:56):

Right, the parser is the behemoth

Mario Carneiro (Sep 06 2018 at 20:56):

I think there was some example where a relation like x = y [mod n] came up

Mario Carneiro (Sep 06 2018 at 20:57):

but even has_le.le can use variables, like the type or instance - we don't want to permute these

Simon Hudon (Sep 06 2018 at 20:58):

That's true

Mario Carneiro (Sep 06 2018 at 20:59):

I was thinking we can use permutations for which the permuted relation is well typed, but this has exponential growth for large relations

Mario Carneiro (Sep 06 2018 at 21:01):

Alternatively, we can require that permuted variables have the same type as each other, but maybe there are counterexamples where you permute a<->b and c<->d where c : T a and d : T b

Mario Carneiro (Sep 06 2018 at 21:01):

then again, in this case you will certainly be providing the permutation list explicitly so we don't have to guess it

Mario Carneiro (Sep 06 2018 at 21:11):

actually, tactic.wlog is also doing some fancy footwork, and it has no segfault protection of its own

Mario Carneiro (Sep 06 2018 at 21:13):

The signature is

meta def wlog (vars' : list expr) (h_cases fst_case : expr) (perms : list (list expr)) : tactic unit

where vars' is the set of variables being permuted, h_cases is a local constant with the proof of the disjunction, fst_case is the pattern (with variables in the same order as the first permutation), and perms is a list of permutations of vars'

Kevin Buzzard (Sep 06 2018 at 21:28):

Is there a case for splitting off the case of two variables and having two tactics? What I actually want to do is wlog degree f ≤ degree g. Is that not possible? (my goal is symmetric in the polynomials f and g).

Mario Carneiro (Sep 06 2018 at 21:31):

It is possible, indeed the default behavior of wlog should do what you want

Mario Carneiro (Sep 06 2018 at 21:31):

if not, just put using f g at the end

Mario Carneiro (Sep 06 2018 at 21:32):

This example blows my mind:

  have h : p n i ∨ p i m ∨ p m i, from sorry,
  wlog : p n i := h using n m i,

It infers the permutation list [n m i, i m n, m i n]

Mario Carneiro (Sep 06 2018 at 21:38):

Oh! The example (and tactic) is actually broken, the test doesn't actually finish the proof so it doesn't notice

Simon Hudon (Sep 06 2018 at 21:46):

It's sometimes baffling how much we can live with bugs in proof tactics


Last updated: Dec 20 2023 at 11:08 UTC