Zulip Chat Archive

Stream: lean4

Topic: Checking `isType` with max in level parameters


Adam Topaz (Nov 21 2023 at 14:17):

Consider the following example:

import Lean

open Lean

elab "foo%" t:term : term => do
  let t  Elab.Term.elabTerm t none
  let tp  Meta.inferType t
  unless tp.isType do throwError "ERROR"
  return t

#check foo% (Nat × Nat)

This results in ERROR, I think because the match in isType asks for .sort (.succ _), but in this case it has the form .sort (.max (.succ _) (.succ _)). Is there a more robust way to check whether something is a type that allows for max in the level parameters?

Alex J. Best (Nov 21 2023 at 14:29):

I'm sure I've had to deal with this somewhere I just can't remember the short solution.
You can use docs#Lean.Level.isNeverZero I think, but maybe there is a function somewhere doing exactly what you want.

Marcus Rossel (Nov 21 2023 at 14:30):

import Lean
open Lean

elab "foo%" t:term : term => do
  let t  Elab.Term.elabTerm t none
  let tp  Meta.inferType t
  let tp'  instantiateMVars tp
  unless tp'.isType do throwError "ERROR"
  return t

#check foo% (Nat × Nat)

Adam Topaz (Nov 21 2023 at 14:30):

Aha, great, yeah I thought it may have something to do with the level mvars. Thanks!

Alex J. Best (Nov 21 2023 at 14:30):

#3682 is what I was remembering

Adam Topaz (Nov 21 2023 at 14:33):

@Marcus Rossel that works for Nat, but I think what Alex points out is still an issue:

import Lean

open Lean

elab "foo%" t:term : term => do
  let t  Elab.Term.elabTerm t none
  let tp  Meta.inferType t
  let tp  instantiateMVars tp
  unless tp.isType do throwError "ERROR"
  return t

universe u v

#check foo% (ULift.{u} Nat × ULift.{v} Nat) -- ERROR

Adam Topaz (Nov 21 2023 at 15:29):

I think I'll introduce

/-- If an `Expr` has the form `Type u`, then return `some u`, otherwise `none`. -/
def type? : Expr  Option Level
  | .sort u => u.dec
  | _ => none

thoughts?

Alex J. Best (Nov 21 2023 at 17:30):

LGTM yes


Last updated: Dec 20 2023 at 11:08 UTC