Search code examples
isabelleproof

membership proof


I need to prove the following:

lemma  "m = min_list(x#xs) ⟹ m ∈ set (x#xs)"

In plain English, I need to prove that the return value from "min_list (x#xs)" is always a member of (x#xs)

I tried:

apply(induct xs)
apply(auto)

I also tried to reuse existing lemmas for the min_list by using:

find_theorems min_list

The sub-goal at this point is so long that I do not know how to proceed.

I am not looking for a full answer just hints on how to approach this lemma. Moreover, is this proof an easy one or significantly difficult one for someone just learning Isabelle?


Solution

  • Spoiler: it is possible to use the standard list induction and auto to prove the theorem, i.e. something similar to by (induct xs ...) (auto simp: ...). I deliberately left out sections in the proof for you to fill in on your own. You will need to think about if any variables (i.e. m or x) need to be specified as arbitrary and also understand what information the simplifier may need (look for clues in the specification of min_list in the theory List).

    With regard to your question about the difficulty of the problem, I believe, that difficulty is a function of experience. Most certainly, when I started learning Isabelle, I was finding it difficult to formalise proofs similar to the one in your question. After a certain time spent coding in Isabelle (by the time of answering this question, I must have accrued an equivalent of 4-5 months of full-time coding in Isabelle), such problems no longer seem to present a significant challenge for me. Of course, there are other factors that need to be taken into account, e.g. previous training in mathematics or logic and previous coding experience.


    General advice from someone who is learning Isabelle on his own (the advice may not be consistent with the approach that is normally recommended by professional instructors)

    I believe, when proving similar results, it is important to understand that Isabelle is, primarily, a tool for formalisation of 'pen-and-paper' proofs. Therefore, it is important to have the 'pen-and-paper' proof at hand before trying to formalise it. I would suggest the following general approach when attacking similar problems:

    1. Write the proof on paper.
    2. Formalise the proof using Isar, providing as many details as possible and not caring too much about the length of the proof. Also, try not to rely on the tools for automated reasoning (i.e. auto, blast, meson, metis, fastforce) and use direct methods like rule and intro as much as you can.
    3. Once your Isar proof is complete, apply tools for automated reasoning (e.g. auto, blast) to your Isar proof to simplify your proof as much as possible.

    Of course, eventually, it will become increasingly easy to omit 1 and 2 as you make progress in learning Isabelle.

    I can provide further details, e.g. the complete short proof and the long Isar version of the proof.


    UPDATE

    As per your request in the comments, I provide an informal proof.

    Lemma. m = min_list (x # xs) ⟹ m ∈ set (x # xs).

    Remarks. For completeness, I also provide the definition of min_list and some comments about the const set. The definition of min_list can be found in the theory List:

    fun min_list :: "'a::ord list ⇒ 'a" where
    "min_list (x # xs) = (case xs of [] ⇒ x | _ ⇒ min x (min_list xs))"
    

    The const set is defined implicitly and constitutes a part of the datatype infrastructure for list (see the document "Defining (Co)datatypes and Primitively (Co)recursive Functions in Isabelle/HOL" in the standard documentation if Isabelle). In particular, it is called the 'set function' of the datatype. Many basic properties of the const set can be found by inspection/search, e.g. find_theorems list.set. I believe that the theorem thm list.set is representative of the main properties of the const set (I took the liberty to rename the schematic variables in the theorem):

    set [] = {}
    set (?x # ?xs) = insert ?x (set ?xs)
    

    Proof. The proof is by structural induction on the list xs. The induction principle is stated as an unnamed lemma at the beginning of the theory List. For completeness, I restate the induction principle below:

    "P [] ⟹ (⋀a list. P list ⟹ P (a # list)) ⟹ P list"

    Base case: assume xs = [], show m = min_list (x # xs) ⟹ m ∈ set (x # xs) for all x. From the definition of min_list, it is trivial to see that min_list (x # []) = x. Similarly, set (x # []) = {x} can be shown directly from the properties of the const set. Substituting into the predicate above, it remains to show that m = x ⟹ m ∈ {x} for all x. This follows from basic set theory.

    Inductive step: assume ⋀x. m = min_list (x # xs) ⟹ m ∈ set (x # xs), show m = min_list (a # x # xs) ⟹ m ∈ set (a # x # xs) for all a, x and xs. Fix a, x and xs. Assume m = min_list (a # x # xs). Then it remains to show that m ∈ set (a # x # xs). Given m = min_list (a # x # xs), from the definition of min_list, it is easy to infer that either m = a or m = min_list (x # xs). Consider these cases explicitly:

    • Case I: m = a. a ∈ set (a # x # xs) follows from the definitions. Then, m ∈ set (a # x # xs) by substitution.
    • Case II: m = min_list (x # xs). Then, from the assumption ⋀x. m = min_list (x # xs) ⟹ m ∈ set (x # xs) it follows that m ∈ set (x # xs). Thus, m ∈ set (a # x # xs) follows from the properties of set.

    In all possible cases m ∈ set (a # x # xs), which is what was required to prove.

    Thus, the proof is concluded.

    Concluding thoughts. Try converting this informal proof to an Isar proof. Also, please note that the proof may not be ideal - I might make edits to the proof later.