Zulip Chat Archive
Stream: new members
Topic: Applying tactic `cases` on a non-variable
Gabriel Alfour (Nov 09 2023 at 09:06):
In tactic mode, in my hypothesis, I have something of an application (like f x
), and I'd like to do cases
on it.
In Coq, when I do so, all instances of f x
get pattern-matched over. In Lean4, nothing happens.
I have tried:
- Doing something like
let fx := f x
, and then rewriting usingrw [fx,\left fx] at hypothesis
, but does not work either. - Doing something like
let fx := fx
, thenlet fx_eq : fx = f x := rfl
and thencases fx
, but it does not work either. Not evenfx
gets destructed.
What would be the Lean4 way of performing this step?
Code below if anyone is interested
inductive ast : Type
| Lam : String -> ast -> ast
| Var : String -> ast
| App : ast -> ast -> ast
-- rewriting
inductive rewrite_step_result : Type
| Finish
| Next : ast -> rewrite_step_result
open ast
open rewrite_step_result
def substitute (expr : ast) (var : String) (sub : ast) :=
match expr with
| Var var' => if var = var' then sub else Var var'
| App f arg => App (substitute f var sub) (substitute arg var sub)
| Lam var' body => if var = var' then Lam var' body else Lam var' (substitute body var sub)
def rewrite_step : ast -> rewrite_step_result
| Var _var => Finish
| Lam _var _body => Finish
| App f arg => (
match rewrite_step f with
| Finish => (
match rewrite_step arg with
| Finish => (
match f with
| Lam var body => Next (substitute body var arg)
| _ => Finish
)
| Next arg' => Next (App f arg')
)
| Next f' => Next (App f' arg)
)
def is_normal (expr : ast) := rewrite_step expr = Finish
open Nat
def rewrite_n_steps (expr : ast) (n : Nat) :=
match n with
| zero => Next expr
| succ n' => (
match rewrite_step expr with
| Finish => Finish
| Next expr' => rewrite_n_steps expr' n'
)
def terminates (expr : ast) := ∃ n , rewrite_n_steps expr n = Finish
def looper : ast :=
App (Lam "x" (App (Var "x") (Var "x"))) (Lam "x" (App (Var "x") (Var "x")))
theorem looper_loops : rewrite_n_steps looper 1 = Next looper :=
by
eq_refl
theorem looper_loops_forever : forall n , rewrite_n_steps looper n = Next looper :=
by
intro n
induction n with
| zero => eq_refl
| succ _ ih =>
exact ih
theorem non_terminating : ∃ (expr : ast) , ¬terminates expr :=
by
exists looper
unfold terminates
intro tl
let ⟨ n , ih ⟩ := tl
have ih' : (rewrite_n_steps looper n = Next looper) := looper_loops_forever n
rw [ih] at ih'
contradiction
namespace Typed
inductive type : Type
| Nat
| Fun : type -> type -> type
deriving DecidableEq
inductive tast : Type
| TVar : String -> tast
| TApp : tast -> tast -> tast
| TLam : String -> type -> tast -> tast
open tast
def remove_types : tast -> ast
| TLam v _ty body => Lam v (remove_types body)
| TVar v => Var v
| TApp f arg => App (remove_types f) (remove_types arg)
namespace Typecheck
inductive result : Type
| Fail
| Succeed : type -> result
def context : Type := List (String × type)
open result
open type
def main (ctx : context) : tast -> result
| TVar v => (
match List.lookup v ctx with
| none => Fail
| some ty => Succeed ty
)
| TLam v ty body => (
let ctx := List.cons (v , ty) ctx
main ctx body
)
| TApp f arg => (
match main ctx arg with
| Fail => Fail
| Succeed arg_ty => (
match main ctx f with
| Fail => Fail
| Succeed f' => (
match f' with
| Fun in_ty out_ty => (
if in_ty = arg_ty then Succeed out_ty
else Fail
)
| _ => Fail
)
)
)
end Typecheck
open Typecheck
theorem stlc_terminate :
∀ (ctx : context) (tast : tast) (ty : type) ,
main ctx tast = result.Succeed ty -> ∃ n ,
rewrite_n_steps (remove_types tast) n = Finish :=
by
intros ctx tast ty success
induction tast
. exists 1
. rename_i f arg f_ih arg_ih
have f_ih_r := f_ih ?_
. admit
. unfold main at success
-- Attempt 1
-- cases (main ctx arg)
-- Attempt 2
-- let marg := main ctx arg
-- rewrite [marg] at success
-- Attempt 3
-- let marg := main ctx arg
-- have marg_eq : marg = main ctx arg := rfl
-- rewrite [← marg_eq] at success arg_ih
-- cases marg
. sorry
. sorry
end Typed
-- environment eval
-- inductive eval_step_result : Type
-- def eval_step
Ruben Van de Velde (Nov 09 2023 at 09:13):
Did I not see someone pointing out cases h : f x
to you in another thread?
Gabriel Alfour (Nov 09 2023 at 09:19):
@Ruben Van de Velde I have tried many permutations that were pointed to me, I might have missed that one, let me check
Gabriel Alfour (Nov 09 2023 at 09:21):
@Ruben Van de Velde
still the same problem, f x
in the hypotheses (main ctx arg
in the code) does not get destructed
But I get an equality relation on it!!! Thanks
Is this the expected way to do so in Lean4? Looks a bit verbose (comparable to case_eq
in Coq), but if it is, I can make-do with it!
Last updated: Dec 20 2023 at 11:08 UTC