1
4

2 回答 2

3

lemma bij_iff_ex_identity : "bij_betw f A B ⟷ (∃ g. g∘f = restrict id B ∧ f∘g = restrict id A)"

I think this is not exactly what you want an I am doubtful that it is true. g∘f = restrict id B does not mean that g∘f and id are equal on B. It means that the total function g∘f (and there are only total functions in HOL) equals the total function restrict id B. The latter returns id x on x∈B and undefined otherwise. So to make this equality true, g needs to output undefined whenever the input of f is not in B. But how would g know that!

If you want to use restrict, you could write restrict (g∘f) B = restrict id B. But personally, I would rather go for the simpler (∀x∈B. (g∘f) x = x).

So the corrected theorem would be:

lemma bij_iff_ex_identity : "bij_betw f A B ⟷ (∃ g. (∀x∈A. (g∘f) x = x) ∧ (∀y∈B. (f∘g) y = y))"

(Which is still wrong, by the way, as quickcheck tells me in Isabelle/jEdit, see the output window. If A has one element and B is empty, f cannot be a bijection. So the theorem you are attempting is actually mathematically not true. I will not attempt to fix it, but just answer the remaining lines.

unfolding bij_betw_def inj_on_def restrict_def iffI

The iffI here has no effect. Unfolding can only apply theorems of the form A = B (unconditional rewriting rules). iffI is not of that form. (Use thm iffI to see.)

proof

Personally, I don't use the bare form proof but always proof - or proof (some method). Because proof just applies some default method (in this case, equivalent to (rule iffI), so I think it's better to make it explicit. proof - just starts the proof without applying an extra method.

let ?g = "restrict (λ y. (if f x = y then x else undefined)) B"

You have an unbound variable x here. (Note the background color in the IDE.) That is most likely not what you want. Formally, it is allowed, but x will be treated as if it was some arbitrary constant.

Generally, I don't think there is any way to define g in a simple way (i.e., only with quantifiers and function applications and if-then-else). I think the only way to define an inverse (even if you know it exists), is to use the THE operator, because you need to say something like g y is "the" x such that f x = y. (And then later in the proof you will run into a proof obligation that it indeed exists and that it is unique.) See the definition of inv_into in Hilbert_Choice.thy (except it uses SOME not THE). Maybe for starters, try to do the proof just using the existing inv_into constant.

assume "(∀x∈A. ∀y∈A. f x = f y ⟶ x = y)"

All assume commands must have assumptions exactly as the are in the proof goal. You can test whether you wrote it right by just temporarily writing the command show A for A (that's an unprovable goal that would, however, finish the proof, so it tricks Isabelle into checking if it would). If this command does not give an error, you got the assumes right. In your cases, you didn't, it should be (∀x∈A. ∀y∈A. f x = f y ⟶ x = y) ∧ f ' A = B. (' is the backtick symbol here. Markup doesn't let me write it.)

My recommendation: Try the proof with bij instead of bij_betw first. (One direction is in BNF_Fixpoint_Base.o_bij if you want to cheat.) Once done, you can try to generalize.

于 2021-04-16T20:22:38.833 回答
2

I agree with the insightful remarks provided by Dominique Unruh. However, I would like to mention that a theorem that captures the idea underlying the theorem that you are trying to prove already exists in the source code of the main library of Isabelle/HOL. In fact, it exists in at least two different formats: let me name them the traditional Isabelle/HOL format and the canonical FuncSet format. For the former one, see the theorem bij_betw_iff_bijections:

"bij_betw f A B ⟷ (∃g. (∀x ∈ A. f x ∈ B ∧ g(f x) = x) ∧ (∀y ∈ B. g y ∈ A ∧ f(g y) = y))"

The situation is a little bit more complicated with FuncSet. There does not seem to exist a single theorem that captures the idea. However, together, the theorems bij_betwI, bij_betw_imp_funcset and inv_into_funcset are nearly equivalent to the theorem that you are trying to state. Let me provide a sketch of how one could express this theorem in a manner that would be considered reasonably canonical in the FuncSet sense (try to prove it yourself):

lemma bij_betw_iff:
  shows "bij_betw f A B ⟷
    (
      ∃g.
        (∀x. x∈A ⟶ g (f x) = x) ∧
        (∀y. y∈B ⟶ f (g y) = y) ∧
        f ∈ A → B ∧
        g ∈ B → A
    )"
sorry

I would also like to repeat the advice given by Dominique Unruh and provide several side remarks:

My recommendation: Try the proof with bij instead of bij_betw first.

Indeed, this is a very good idea. In general, by trying to restrict the problem to explicitly defined sets A and B, instead of working directly with types, you touched upon a topic that is known as relativization in logic. For a mild layman's introduction see, for example, https://leanprover.github.io/logic_and_proof/first_order_logic.html [1], for a slightly more thorough introduction in the context of set theory see [2, chapter 12]. As you have probably noticed by now, it is not that easy to relativize theorems in Isabelle/HOL and requires additional proof effort. However, there exists an extension of Isabelle/HOL that allows for the automation of the process of the relativization of theorems. For more information about this extension see the article From Types to Sets by Local Type Definition in Higher-Order Logic by Ondřej Kunčar and Andrei Popescu [3]. There also exists a large scale application example of the framework [4]. Independently, I am working on making this extension more user-friendly and very slowly approaching the final stages in my efforts: see https://gitlab.com/user9716869/tts_extension. Thus, in principle, if you know how to use Types-To-Sets and you accept its axioms, then it is sufficient to prove the theorem with bij, e.g.,

"bij f ⟷ (∃g. (∀x. g (f x) = x) ∧ (∀y. f (g y) = y))",

Then, the theorems like bij_betw_iff_bijections and bij_betw_iff can be synthesized automatically for free upon a click of a button (almost...).


Finally, for completeness, let me offer my own advice with regard to your queries (although, as I mentioned, I agree with everything stated by Dominique Unruh)

how to expand the relevant definitions and then simplify them with function applications. I have followed some Isabelle (2021) examples/tutorials about both the apply-style simp, and structured style Isar proof but couldn't use the Isar proof fluently. Once I started the proof command, I don't know how to simp or move any further.

I believe that the best way to learn what you are trying to learn is by following through the exercises in the book Concrete Semantics by Tobias Nipkow and Gerwin Klein [5]. Additionally, I would also look through A Proof Assistant for Higher-Order Logic by Tobias Nipkow et al [6](it is slightly outdated, but I found it to be useful specifically for learning apply-style scripting/direct rule application). By the way, I have mostly self-taught myself Isabelle from these books without any prior experience in formal methods.

Isar has the new way of assumes ... shows ... for stating the theorem. Is there similar support for proving iff's (⟷) like the example above? Without it, there is no access to assms etc., and is it necessary to assume everything except the conclusion during the proof.

I will make the advice given by Dominique Unruh more explicit: use rule iffI or intro iffI for this.

Edit. When you use rule iffI (or similar) to start your structured Isar proof, you need to state your assumptions explicitly for every subgoal (using the assume ... show ... paradigm). However, there is a tool that can generate such boilerplate Isar code automatically. It is called Sketch-and-Explore and you can find it in the directory HOL/ex of the main library of Isabelle/HOL. In this case, all you need to do is to type sketch(rule iffI) and the assume/show paradigm will be generated automatically for every subgoal.

References

  1. Avigad J, Lewis RY, and van Doorn F. Logic and Proof.
  2. Jech T. Set theory. 3rd ed. Heidelberg: Springer; 2006. (Pure and applied mathematics, a series of monographs and textbooks).
  3. Kunčar O, Popescu A. From Types to Sets by Local Type Definition in Higher-Order Logic. Journal of Automated Reasoning. 2019;62(2):237–60.
  4. Immler F, Zhan B. Smooth Manifolds and Types to Sets for Linear Algebra in Isabelle/HOL. In: 8th ACM SIGPLAN International Conference on Certified Programs and Proofs. New York: ACM; 2019. p. 65–77. (CPP 2019).
  5. Nipkow T, Klein G. Concrete Semantics with Isabelle/HOL. Heidelberg: Springer-Verlag; 2017. (http://concrete-semantics.org/)
  6. Nipkow T, Paulson LC, Wenzel M. A Proof Assistant for Higher-Order Logic. Heidelberg: Springer-Verlag; 2017.
于 2021-04-16T23:35:51.587 回答