Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/HOL/Isar_Examples/   (Beweissystem Isabelle Version 2025-1©)  Datei vom 16.11.2025 mit Größe 14 kB image not shown  

Quelle  Basic_Logic.thy

  Sprache: Isabelle
 

(*  Title:      HOL/Isar_Examples/Basic_Logic.thy
    Author:     Makarius

Basic propositional and quantifier reasoning.
*)


section Basic logical reasoning

theory Basic_Logic
  imports Main
begin


subsection Pure backward reasoning

text 
 In order to get a first idea of how Isabelle/Isar proof documents may look
 like, we consider the propositions I, K, and S. The following (rather
 explicit) proofs should require little extra explanations.
 


lemma I: "A A"
proof
  assume A
  show A by fact
qed

lemma K: "A B A"
proof
  assume A
  show "B A"
  proof
    show A by fact
  qed
qed

lemma S: "(A B C) (A B) A C"
proof
  assume "A B C"
  show "(A B) A C"
  proof
    assume "A B"
    show "A C"
    proof
      assume A
      show C
      proof (rule mp)
        show "B C" by (rule mp) fact+
        show B by (rule mp) fact+
      qed
    qed
  qed
qed

text 
 Isar provides several ways to fine-tune the reasoning, avoiding excessive
 detail. Several abbreviated language elements are available, enabling the
 writer to express proofs in a more concise way, even without referring to
 any automated proof tools yet.

 Concluding any (sub-)proof already involves solving any remaining goals by
 assumption🪙This is not a completely trivial operation, as proof by
 assumption may involve full higher-order unification.
. Thus we may skip the
 rather vacuous body of the above proof.
 


lemma "A A"
proof
qed

text 
 Note that the 🪙proof command refers to the rule method (without
 arguments) by default. Thus it implicitly applies a single rule, as
 determined from the syntactic form of the statements involved. The 🪙by
 command abbreviates any proof with empty body, so the proof may be further
 pruned.
 


lemma "A A"
  by rule

text 
 Proof by a single rule may be abbreviated as double-dot.
 


lemma "A A" ..

text 
 Thus we have arrived at an adequate representation of the proof of a
 tautology that holds by a single standard rule.🪙Apparently, the
 rule here is implication introduction.


 🪙
 Let us also reconsider K. Its statement is composed of iterated
 connectives. Basic decomposition is by a single rule at a time, which is why
 our first version above was by nesting two proofs.

 The intro proof method repeatedly decomposes a goal's conclusion.🪙The
 dual method is elim, acting on a goal's premises.

 


lemma "A B A"
proof (intro impI)
  assume A
  show A by fact
qed

text Again, the body may be collapsed.

lemma "A B A"
  by (intro impI)

text 
 Just like rule, the intro and elim proof methods pick standard
 structural rules, in case no explicit arguments are given. While implicit
 rules are usually just fine for single rule application, this may go too far
 with iteration. Thus in practice, intro and elim would be typically
 restricted to certain structures by giving a few rules only, e.g.🪙proof
 (intro impI allI)
to strip implications and universal quantifiers.

 Such well-tuned iterated decomposition of certain structures is the prime
 application of intro and elim. In contrast, terminal steps that solve a
 goal completely are usually performed by actual automated proof methods
 (such as 🪙by blast.
 



subsection Variations of backward vs.forward reasoning

text 
 Certainly, any proof may be performed in backward-style only. On the other
 hand, small steps of reasoning are often more naturally expressed in
 forward-style. Isar supports both backward and forward reasoning as a
 first-class concept. In order to demonstrate the difference, we consider
 several proofs of A B B A.

 The first version is purely backward.
 


lemma "A B B A"
proof
  assume "A B"
  show "B A"
  proof
    show B by (rule conjunct2) fact
    show A by (rule conjunct1) fact
  qed
qed

text 
 Above, the projection rules conjunct1 / conjunct2 had to be named
 explicitly, since the goals B and A did not provide any structural clue.
 This may be avoided using 🪙from to focus on the A B assumption as the
 current facts, enabling the use of double-dot proofs. Note that 🪙from
 already does forward-chaining, involving the conjE rule here.
 


lemma "A B B A"
proof
  assume "A B"
  show "B A"
  proof
    from A B show B ..
    from A B show A ..
  qed
qed

text 
 In the next version, we move the forward step one level upwards.
 Forward-chaining from the most recent facts is indicated by the 🪙then
 command. Thus the proof of B A from A B actually becomes an
 elimination, rather than an introduction. The resulting proof structure
 directly corresponds to that of the conjE rule, including the repeated
 goal proposition that is abbreviated as ?thesis below.
 


lemma "A B B A"
proof
  assume "A B"
  then show "B A"
  proof                    ― rule conjE of A B
    assume B A
    then show ?thesis ..   ― rule conjI of B A
  qed
qed

text 
 In the subsequent version we flatten the structure of the main body by doing
 forward reasoning all the time. Only the outermost decomposition step is
 left as backward.
 


lemma "A B B A"
proof
  assume "A B"
  from A B have A ..
  from A B have B ..
  from B A show "B A" ..
qed

text 
 We can still push forward-reasoning a bit further, even at the risk of
 getting ridiculous. Note that we force the initial proof step to do nothing
 here, by referring to the - proof method.
 


lemma "A B B A"
proof -
  {
    assume "A B"
    from A B have A ..
    from A B have B ..
    from B A have "B A" ..
  }
  then show ?thesis ..         ― rule impI
qed

text 
 🪙
 With these examples we have shifted through a whole range from purely
 backward to purely forward reasoning. Apparently, in the extreme ends we get
 slightly ill-structured proofs, which also require much explicit naming of
 either rules (backward) or local facts (forward).

 The general lesson learned here is that good proof style would achieve just
 the 🪙right balance of top-down backward decomposition, and bottom-up
 forward composition. In general, there is no single best way to arrange some
 pieces of formal reasoning, of course. Depending on the actual applications,
 the intended audience etc., rules (and methods) on the one hand vs.facts
 on the other hand have to be emphasized in an appropriate way. This requires
 the proof writer to develop good taste, and some practice, of course.

 🪙
 For our example the most appropriate way of reasoning is probably the middle
 one, with conjunction introduction done after elimination.
 


lemma "A B B A"
proof
  assume "A B"
  then show "B A"
  proof
    assume B A
    then show ?thesis ..
  qed
qed



subsection A few examples from ``Introduction to Isabelle''

text 
 We rephrase some of the basic reasoning examples of cite"isabelle-intro", using HOL rather than FOL.
 



subsubsection A propositional proof

text 
 We consider the proposition P P P. The proof below involves
 forward-chaining from P P, followed by an explicit case-analysis on the
 two 🪙identical cases.
 


lemma "P P P"
proof
  assume "P P"
  then show P
  proof                    ― rule disjE: \smash{$\infer{C}{A B & \infer*{C}{[A]} & \infer*{C}{[B]}}$}
    assume P show P by fact
  next
    assume P show P by fact
  qed
qed

text 
 Case splits are 🪙not hardwired into the Isar language as a special
 feature. The 🪙next command used to separate the cases above is just a
 short form of managing block structure.

 🪙
 In general, applying proof methods may split up a goal into separate
 ``cases'', i.e.new subgoals with individual local assumptions. The
 corresponding proof text typically mimics this by establishing results in
 appropriate contexts, separated by blocks.

 In order to avoid too much explicit parentheses, the Isar system implicitly
 opens an additional block for any new goal, the 🪙next statement then
 closes one block level, opening a new one. The resulting behaviour is what
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "macro" is null
 an induction base case (which does not introduce local assumptions) would
 🪙not require 🪙next to separate the subsequent step case.

 🪙
 In our example the situation is even simpler, since the two cases actually
 coincide. Consequently the proof may be rephrased as follows.
 


lemma "P P P"
proof
  assume "P P"
  then show P
  proof
    assume P
    show P by fact
    show P by fact
  qed
qed

text Again, the rather vacuous body of the proof may be collapsed.
 Thus the case analysis degenerates into two assumption steps, which
 are implicitly performed when concluding the single rule step of the
 double-dot proof as follows.


lemma "P P P"
proof
  assume "P P"
  then show P ..
qed


subsubsection A quantifier proof

text 
 To illustrate quantifier reasoning, let us prove
 (x. P (f x)) (y. P y). Informally, this holds because any a with
 P (f a) may be taken as a witness for the second existential statement.

 The first proof is rather verbose, exhibiting quite a lot of (redundant)
 detail. It gives explicit rules, even with some instantiation. Furthermore,
 we encounter two new language elements: the 🪙fix command augments the
 context by some new ``arbitrary, but fixed'' element; the 🪙is annotation
 binds term abbreviations by higher-order pattern matching.
 


lemma "(x. P (f x)) (y. P y)"
proof
  assume "x. P (f x)"
  then show "y. P y"
  proof (rule exE)             ― rule exE: \smash{$\infer{B}{x. A(x) & \infer*{B}{[A(x)]_x}}$}
    fix a
    assume "P (f a)" (is "P ?witness")
    then show ?thesis by (rule exI [of P ?witness])
  qed
qed

text 
 While explicit rule instantiation may occasionally improve readability of
 certain aspects of reasoning, it is usually quite redundant. Above, the
 basic proof outline gives already enough structural clues for the system to
 infer both the rules and their instances (by higher-order unification). Thus
 we may as well prune the text as follows.
 


lemma "(x. P (f x)) (y. P y)"
proof
  assume "x. P (f x)"
  then show "y. P y"
  proof
    fix a
    assume "P (f a)"
    then show ?thesis ..
  qed
qed

text 
 Explicit -elimination as seen above can become quite cumbersome in
 practice. The derived Isar language element ``🪙obtain'' provides a more
 handsome way to do generalized existence reasoning.
 


lemma "(x. P (f x)) (y. P y)"
proof
  assume "x. P (f x)"
  then obtain a where "P (f a)" ..
  then show "y. P y" ..
qed

text 
 Technically, 🪙obtain is similar to 🪙fix and 🪙assume together with a
 soundness proof of the elimination involved. Thus it behaves similar to any
 other forward proof element. Also note that due to the nature of general
 existence reasoning involved here, any result exported from the context of
 an 🪙obtain statement may 🪙not refer to the parameters introduced there.
 



subsubsection Deriving rules in Isabelle

text 
 We derive the conjunction elimination rule from the corresponding
 projections. The proof is quite straight-forward, since Isabelle/Isar
 supports non-atomic goals and assumptions fully transparently.
 


theorem conjE: "A B ==> (A ==> B ==> C) ==> C"
proof -
  assume "A B"
  assume r: "A ==> B ==> C"
  show C
  proof (rule r)
    show A by (rule conjunct1) fact
    show B by (rule conjunct2) fact
  qed
qed

end

Messung V0.5 in Prozent
C=83 H=82 G=82

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-06-10) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.