theory Demo05
imports Main
begin

section {* Isar *}

lemma "\<lbrakk> A; B \<rbrakk> \<Longrightarrow> A \<and> B"
proof (rule conjI)
  assume a: "A"
  from a show "A" by assumption
next
  assume b: "B"
  from b show "B" by assumption
qed


lemma 
  assumes a: "A"
  assumes b: "B"
  shows "A \<and> B"
proof (rule conjI)
  from a show "A" by assumption
  from b show "B" by assumption
qed


lemma "(x::nat) + 1 = 1 + x"
proof -
  have a: "x + 1 = Suc x" by simp
  have b: "1 + x = Suc x" by simp
  show "x + 1 = 1 + x" by (simp only: a b)
qed

-- ------------------------------------------------

text {* . = by assumption,  .. = by rule *}

lemma "\<lbrakk> A; B \<rbrakk> \<Longrightarrow> B \<and> A"
proof 
  assume a: "A" and b: "B"
  from a show "A" .
  from b show "B" .
qed

lemma "\<lbrakk> A; B \<rbrakk> \<Longrightarrow> B \<and> A" 
proof -
  assume a: "A" and b: "B"
  from b and a show "B \<and> A" ..
qed


text {* backward/forward *}

lemma "A \<and> B \<longrightarrow> B \<and> A"
proof
  assume ab: "A \<and> B"
  from ab show "B \<and> A"
  proof
    assume a: "A" and b: "B"
    from b a show "B \<and> A" ..
  qed
qed

text {* dealing with cases *}

lemma "A \<or> B \<longrightarrow> B \<or> A"
proof
  assume ab: "A \<or> B"
  from ab show "B \<or> A" proof
    assume a: "A"
    from a show "B \<or> A" ..
  next
    assume b: "B"
    from b show "B \<or> A" ..
  qed
qed

-- "Backtick: refer to facts without naming them"

lemma "A \<and> B \<longrightarrow> B \<and> A"
proof
  assume "A \<and> B"
  from `A \<and> B` show "B \<and> A"
  proof
    assume "A" "B"
    from `B` `A` show "B \<and> A" ..
  qed
qed

-- "then = from this"

lemma "A \<and> B \<longrightarrow> B \<and> A"
proof
  assume "A \<and> B"
  then show "B \<and> A"
  proof
    assume "B" "A"
    then show "B \<and> A" ..
  qed
qed


text{* fix *}

lemma assumes P: "\<forall>x. P x" shows "\<forall>x. P (f x)"
proof
  fix a
  from P show "P (f a)" ..
qed

text{* Proof text can only refer to global constants, free variables
in the lemma, and local names introduced via fix or obtain. *}

lemma assumes Pf: "\<exists>x. P (f x)" shows "\<exists>y. P y"
proof -
  from Pf show ?thesis
  proof
    fix x
    assume "P (f x)"
    then show ?thesis ..
  qed
qed


text {* obtain *}

lemma assumes Pf: "\<exists>x. P (f x)" shows "\<exists>y. P y"
proof -
  from Pf obtain x where "P(f x)" ..
  then show "\<exists>y. P y" ..
qed

lemma assumes ex: "\<exists>x. \<forall>y. P x y" shows "\<forall>y. \<exists>x. P x y"
proof
  fix y
  from ex obtain x where "\<forall>y. P x y" ..
  then have "P x y" ..
  then show "\<exists>x. P x y" ..
qed

lemma 
  assumes A: "\<forall>x y. P x y \<and> Q x y" 
  shows "\<exists>x y. P x y \<and> Q x y"
proof -
  from A obtain x y where P: "P x y" and Q: "Q x y" by blast
  then show ?thesis by blast
qed

lemma "\<exists>x. P x \<longrightarrow> (\<forall>x. P x)"
oops


end
