Zulip Chat Archive

Stream: metaprogramming / tactics

Topic: Distinguishing Type from Prop


Geoffrey Irving (Feb 20 2024 at 14:47):

If I have a Lean.Expr representing a type, how do I tell what the sort is? I want to distinguish Prop types from Type types.

Geoffrey Irving (Feb 20 2024 at 14:47):

In particular, Lean.Expr.isProp doesn't do it, as that's for checking if the expr is literally Prop.

Damiano Testa (Feb 20 2024 at 14:53):

Is the issue that you want to pass ← inferType e to isProp, maybe?

Geoffrey Irving (Feb 20 2024 at 14:53):

Ah, yep, that seems right.

Damiano Testa (Feb 20 2024 at 14:54):

(Otherwise, if you could give a #mwe, it would help me understand what the problem is! :smile: )

Patrick Massot (Feb 20 2024 at 15:03):

That trap gets me every time.

Damiano Testa (Feb 20 2024 at 15:05):

Same here, which is why it was my first suggestion!

Eric Wieser (Feb 20 2024 at 15:06):

The docstring for docs#Lean.Expr.isProp is wrong, right?

Eric Wieser (Feb 20 2024 at 15:06):

There is a bogus "a" that changes the meaning to be the wrong thing

Geoffrey Irving (Feb 20 2024 at 15:07):

I mean, there can be many sort 0s if you interpret identity as being literal residency in memory. That might have been the thought process.

Geoffrey Irving (Feb 20 2024 at 15:07):

But yes, that was part of my confusion too.

Geoffrey Irving (Feb 20 2024 at 15:08):

On reflection, though, you can't tell without being in CoreM or MetaM, though, which is a clue.

Damiano Testa (Feb 20 2024 at 15:08):

Here is a self-contained example, in case it helps someone else who might stumble here:

import Mathlib.Tactic.RunCmd

open Lean Meta in
run_cmd Elab.Command.liftTermElabM do  -- `(false, true)`
  let tExpr   := .const ``True []
  let notProp := tExpr.isProp
  let isProp  := ( inferType tExpr).isProp
  logInfo m!"{(notProp, isProp)}"

Eric Wieser (Feb 20 2024 at 15:10):

lean4#3420 fixes the docstring

Eric Wieser (Feb 20 2024 at 15:10):

I think it's just a copy paste error where all the other functions are referring to families of values

Eric Wieser (Feb 20 2024 at 15:11):

(a constant, an element of the form $x, etc)

Damiano Testa (Feb 20 2024 at 15:11):

Eric Wieser said:

lean4#3420 fixes the docstring

I wonder if I should try to maintainer merge it...

Kevin Buzzard (Feb 20 2024 at 15:47):

I wouldn't bother cluttering up the PR :-)

Adam Topaz (Feb 20 2024 at 17:37):

FWIW, I quite like the following pattern:

import Lean

def foo : Prop := True

open Lean in
#eval show MetaM Unit from do
  let some c := ( getEnv).find? `foo | unreachable!
  let .sort .zero := c.type | throwError "Not a prop"
  IO.println <|  Meta.ppExpr c.type

Adam Topaz (Feb 20 2024 at 17:38):

(no pun intended)

Kyle Miller (Feb 20 2024 at 18:01):

Generally, you should prefer docs#Lean.Meta.isProp, docs#Lean.Meta.isProof, and docs#Lean.Meta.isType over the ones in the Lean.Expr namespace, unless you know you don't have any metavariables or level parameter reductions to do.

Adam Topaz (Feb 20 2024 at 18:03):

Oh, I wasn't aware that Meta.isProp existed!

Eric Wieser (Feb 20 2024 at 18:14):

Should Expr.isProp be renamed, given it means something entirely unrelated to Meta.isProp ?

Eric Wieser (Feb 20 2024 at 18:15):

(does it even compile to something more useful than the clearer e == .sort .zero?)

Kyle Miller (Feb 20 2024 at 18:20):

I always get confused by both of them. I wonder if Meta.isProp could be renamed to something that makes it clear that Meta.isProp p is checking that p is a proposition, rather than being Prop itself.

It could be split into Meta.isProp as a parallel to Expr.isProp and perhaps Meta.isProposition, which would be equivalent to Meta.isProp (<- inferType p).

Kyle Miller (Feb 20 2024 at 18:21):

There's a strong precedent for is in the matching functions to mean that it really is, not is-a

Kyle Miller (Feb 20 2024 at 18:21):

An alternative name suggestion for Meta.isProposition is Meta.isAProp

Jannis Limperg (Feb 20 2024 at 18:23):

If you do this renaming (which I'm a fan of), please post a big fat warning somewhere when the behaviour of isProp changes.

Eric Rodriguez (Mar 05 2024 at 04:04):

Let me say quickly that this thread reminded me to take care on which one to use here - I think if stuff isn't renamed, then docstrings pointing both to each other would be a good idea.


Last updated: May 02 2025 at 03:31 UTC