Zulip Chat Archive
Stream: general
Topic: How to nomatch on a custom less-than type?
nrs (Oct 26 2024 at 14:32):
Since lt
below always has a type mismatch, wouldn't we expect nomatch lt
to typecheck?
inductive Pos
| one : Pos
| succ : Pos -> Pos
def Pos.toNat : Pos -> Nat
| .one => 1
| .succ n => .succ (n.toNat)
inductive LT' : Nat -> Nat -> Type
| mk : (n : Nat) -> (pos : Pos) -> LT' n (n + pos.toNat)
variable (lt : LT' 0 0)
#check match lt with | .mk nat pos => _ -- type mismatch; has type LT'' nat (nat + pos.toNat) but expected LT'' 0 0
#check match lt with | .mk .. => _ -- type mismatch; has type LT'' 0 (0 + ?m.15735.toNat) : Type but is expected to have type LT'' 0 0 : Type
#check nomatch lt -- missing cases _
Trebor Huang (Oct 26 2024 at 15:00):
The mismatch is the "Lean doesn't know if it matches" kind, not the "Lean knows it definitely doesn't match" kind. Only the latter warrants a nomatch.
nrs (Oct 26 2024 at 15:03):
Trebor Huang said:
The mismatch is the "Lean doesn't know if it matches" kind, not the "Lean knows it definitely doesn't match" kind. Only the latter warrants a nomatch.
hm. Is there more information I could provide to obtain a contradiction/an empty type? e.g., is there something that can inhabit LT' 0 0 -> Empty
?
Kyle Miller (Oct 26 2024 at 16:49):
This is a standard sort of example of trying to do pattern matching with indices that aren't just constructor applications. One solution is to change the type to "relax" the index using a propositional equality:
inductive LT' : Nat -> Nat -> Type
| mk : (n m : Nat) -> (pos : Pos) -> (h : m = n + pos.toNat) -> LT' n m
variable (lt : LT' 0 0)
#check match lt with | .mk 0 _ pos h => by cases pos <;> cases h
nrs (Oct 26 2024 at 17:11):
Kyle Miller said:
This is a standard sort of example of trying to do pattern matching with indices that aren't just constructor applications. One solution is to change the type to "relax" the index using a propositional equality:
inductive LT' : Nat -> Nat -> Type | mk : (n m : Nat) -> (pos : Pos) -> (h : m = n + pos.toNat) -> LT' n m variable (lt : LT' 0 0) #check match lt with | .mk 0 _ pos h => by cases pos <;> cases h
Thanks for the reply! I will be studying this example
Last updated: May 02 2025 at 03:31 UTC