Skip to content

RFC: mvcgen should automatically recurse into let-bound target assertions #9474

@rish987

Description

@rish987

Proposal

In the following MWE, the call to mvcgen [setZeroHead] leaves us with a rather unsightly proof mode goal:

import Std.Tactic.Do

open Std.Do

set_option mvcgen.warning false

abbrev gns : SVal ((List Nat)::[]) (List Nat) := fun s => SVal.pure s

noncomputable def setZeroHead : StateM (List Nat) Unit := do
  modify fun _ => [1, 0, 1, 2, 3, 4, 5]
  pure ()
  modify fun s => s.tail
  pure ()

theorem setZeroHead_spec :
   ⦃⌜True⌝⦄
   setZeroHead
   ⦃⇓ _ => ⌜∃ ns', #gns = 0 :: ns'⌝⦄ := by
  mvcgen [setZeroHead]
  -- Goal:
  --
  -- s✝ : List Nat
  --
  -- h✝ : ⌜True⌝ s✝
  -- ⊢ₛ
  -- have t := (PUnit.unit, [1, 0, 1, 2, 3, 4, 5]);
  -- (fun a =>
  --       wp⟦do
  --           pure ()
  --           MonadStateOf.modifyGet fun s => (PUnit.unit, s.tail)
  --           pure ()⟧
  --         ⇓x => ⌜∃ ns', #gns tuple = 0 :: ns'⌝,
  --       (⇓x => ⌜∃ ns', #gns tuple = 0 :: ns'⌝).snd).fst
  --   t.fst t.snd
  mintro t
  mvcgen
  mintro t
  mvcgen
  mleave
  exists t.2.tail

Before #9451, mvcgen would leave us at the state we see at mleave (but with the t let-binding definitions inlined). Now that Spec.modifyGet_StateT has a let-binding in its precondition, however, mvcgen gets stuck at the first call to modify, and we have to call mintro t and mvcgen manually to make progress. It seems that mvcgen should probably automatically handle the mintro steps so that the user doesn't have to intervene.

Community Feedback

Follow-up to #9365. cc @sgraf812

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCRequest for comments

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions