Zulip Chat Archive

Stream: general

Topic: expr


Scott Morrison (Sep 09 2018 at 06:14):

Does anyone know the behaviour of meta constant expr.replace : expr → (expr → nat → option expr) → expr?

Scott Morrison (Sep 09 2018 at 06:15):

(I have an expression that has a single mvar somewhere in it; I would like to replace that with an expr.var 0.)

Simon Hudon (Sep 09 2018 at 06:18):

You could try implementing it as e.replace $ λ e' _, if e'.is_mvar then expr.var 0 else none

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

It might not work if replace does not proceed recursively but your attempt should help us decide what to do next.

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

you should probably use the n variable though

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

e.replace $ λ e' n, if e'.is_mvar then expr.var n else none

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

Ooooooh! Is that what it's for? That's so cool!

Scott Morrison (Sep 09 2018 at 06:24):

Neat!

Scott Morrison (Sep 09 2018 at 06:25):

Do you guys have an expr.is_mvar that I'm missing?

Mario Carneiro (Sep 09 2018 at 06:27):

no, looks like you will have to roll your own

Simon Hudon (Sep 09 2018 at 06:27):

I thought it was in mathlib

Simon Hudon (Sep 09 2018 at 06:28):

Ah! In tactic.basic, there it is called is_meta_var

Scott Morrison (Sep 09 2018 at 06:28):

Thanks.

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

should we be more regular in the naming there?

Simon Hudon (Sep 09 2018 at 06:30):

Probably, yes

Chris Hughes (Oct 20 2018 at 19:53):

Is there any documentation anywhere on what all the constructors to expr mean?

Simon Hudon (Oct 20 2018 at 20:28):

Not that I know of. It would be worth writing. What do you want to know?

Scott Morrison (Oct 20 2018 at 21:58):

I would love to have a paragraph on each. I have to re-remember the order of arguments to expr.pi every time I see it.

Chris Hughes (Oct 20 2018 at 22:46):

Essentially what Scott's talking about. What each of the arguments to each constructor represents.

Scott Morrison (Oct 20 2018 at 22:52):

Didn't Ed Ayers write this at some point? He had a draft of some docs on meta stuff, but I think it was never PR'd.

Chris Hughes (Oct 21 2018 at 04:48):

Are expr tts allowed to contain metavariables?

Edward Ayers (Oct 21 2018 at 08:04):

yes

Edward Ayers (Oct 21 2018 at 08:06):

as far as I understand, expr tt means that the expression has been typechecked and fully elaborated.

Edward Ayers (Oct 21 2018 at 08:06):

meta inductive expr (elaborated : bool := tt)
/- A bound variable with a de-Bruijn index. -/
| var      {} : nat  expr
/- A type universe: `Sort u` -/
| sort     {} : level  expr
/- A global constant. These include definitions, constants and inductive type stuff present in the environment as well as hard-coded definitions. -/
| const    {} : name  list level  expr
/- [WARNING] Do not trust the types for `mvar` and `local_const`,
they are sometimes dummy values. Use `tactic.infer_type` instead. -/
/- An `mvar` is a 'hole' yet to be filled in by the elaborator or tactic state. -/
| mvar        (pretty : name)  (unique : name)  (type : expr) : expr
/- A local constant. For example, if our tactic state was `h : P ⊢ Q`, `h` would be a local constant. -/
| local_const (pretty : name) (unique : name) (bi : binder_info) (type : expr) : expr
/- Function application. -/
| app         : expr  expr  expr
/- Lambda abstraction. eg ```(λ a : α, x)`` -/
| lam        (var_name : name) (bi : binder_info) (var_type : expr) (body : expr) : expr
/- Pi type constructor. eg ```(Π a : α, x)`` and ```(α → β)`` -/
| pi         (var_name : name) (bi : binder_info) (var_type : expr) (body : expr) : expr
/- An explicit let binding.-/
| elet       (var_name : name) (type : expr) (assignment : expr) (body : expr) : expr
/- A macro, see the docstring for `macro_def`.
  The list of expressions are local constants and metavariables that the macro depends on.
  -/
| macro       : macro_def  list expr  expr

Edward Ayers (Oct 21 2018 at 08:07):

@Scott Morrison yeah I should PR it at some point.

Edward Ayers (Oct 21 2018 at 08:09):

I build Lean from source with extra docstrings.

Edward Ayers (Oct 21 2018 at 08:22):

binder_info is only used by the elaborator.

Chris Hughes (Oct 21 2018 at 16:24):

Thanks for this.

Chris Hughes (Oct 21 2018 at 17:20):

What does tactic.generalize do?

Simon Hudon (Oct 21 2018 at 18:27):

If you have ⊢ x + 1 ≤ y + 2, generalize ``(y + 2) `z will turn the goal into ⊢ x + 1 ≤ z

Chris Hughes (Oct 21 2018 at 18:28):

Okay thanks.

Simon Hudon (Oct 21 2018 at 18:29):

The interactive version offers more options like adding an assumption h : y + 2 = z

Mario Carneiro (Oct 21 2018 at 22:50):

@Edward Ayers An expr tt may not actually have been typechecked, but it is presumed to at least have the structure to be typechecked

Edward Ayers (Oct 22 2018 at 08:58):

Ok so does expr tt just mean that there are no placeholders?

Gabriel Ebner (Oct 22 2018 at 09:02):

Well, technically yes since "placeholder" is the name used for the macro that represents the _ syntactical form. But both expr ff and expr tt can have metavariables.

Gabriel Ebner (Oct 22 2018 at 09:04):

The big difference between expr ff and expr tt is whether implicit arguments are present. For example the equality x = x is represented in expr ff as app (app (const `eq _) x) x while in expr tt it is represented as app (app (app (const `eq _) t) x) x (one more argument).

Edward Ayers (Oct 22 2018 at 09:31):

What is the difference between implicit and strict_implicit?

Edward Ayers (Oct 22 2018 at 09:32):

For binder_info

Gabriel Ebner (Oct 22 2018 at 09:38):

default = (x : α), implicit = {x : α}, strict_implicit = ⦃x : α⦄, inst_implicit = [x : α], I believe aux_decl is used as a tag for the _match hypotheses but I could be completely mistaken.

Gabriel Ebner (Oct 22 2018 at 09:41):

The difference between {} and ⦃⦄ is how implicit arguments are treated that are not followed by explicit arguments. {} arguments are applied eagerly, while ⦃⦄ arguments are left partially applied:

def foo {x : } :  := x
def bar x :  :  := x
#check foo -- foo : ℕ
#check bar -- bar : Π ⦃x : ℕ⦄, ℕ

Edward Ayers (Oct 22 2018 at 09:55):

In C++ it says that aux_decl is "used to mark local constants representing recursive functions
in recursive equations and match statements."

Mario Carneiro (Oct 22 2018 at 09:57):

aux_decl is used for _match, _fun_match, _let_match and the self reference that appears in recursive pattern matching

Mario Carneiro (Oct 22 2018 at 09:58):

these are not real local constants, but rather trigger recursive compilation when used

Chris Hughes (Oct 23 2018 at 21:50):

If pexpr and expr are more or less the exact same inductive type how are they different? Is it just because in practice we never define them from constructors ourselves and always use the inbuilt functions which treat pexpr and expr differently even though the type doesn't force them to?

Floris van Doorn (Oct 24 2018 at 02:38):

As Gabriel said above, the same term is represented differently as an pexpr than as an expr. Moreover, for both structures there are some constants such as expr.mk_sorry, pexpr.mk_placeholder and pexpr.mk_explicit which only exist in one of the two variants, but not the other. These are not represented by the inductive structure. But mk_placeholder and mk_explicit will be used (for example) by the tactic to_expr.

Chris Hughes (Oct 28 2018 at 16:52):

Is there an easy way of printing an expr in terms of the constructors of expr?

Rob Lewis (Oct 28 2018 at 17:07):

expr.to_raw_fmt

Chris Hughes (Oct 28 2018 at 17:07):

Thanks

Chris Hughes (Nov 04 2018 at 15:52):

If I'm writing a tactic and I have e : expr, which is a proof of equality, how would I do rw e at * say, or simp [e] at * as part of a tactic?

Keeley Hoek (Nov 05 2018 at 00:55):

You can rw another arbitrary expr using rewrite_core. I would have to read the tactic.interactive.rw definition to see how it replaces local hypotheses, too, but that's the idea.

For simp you need to call mk_simp_set and then add your lemma to it. Then you need to pass that data to the built-in function tactic.simplify.

Scott Morrison (Nov 05 2018 at 02:59):

often a cheap way to do these sorts of things is using tactic quotations, e.g. `[simp at *]

Scott Morrison (Nov 05 2018 at 03:00):

I'm guessing you can use antiquotations, and write something like `[simp [%%e] at *].


Last updated: Dec 20 2023 at 11:08 UTC