1

When working with Isabelle’s infinite stream data type, I need this obviously true lemma, but I am unable to figure out how to prove it (as I am not well versed with coinduction yet). How would I go about proving it?

lemma sset_cycle[simp]:
  "xs ≠ [] ⟹ sset (cycle xs) = set xs"
Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139

2 Answers2

2

I'm not an expert on coinduction myself, but coinduction is not required here. I'm not an expert on codatatypes either, but anyway, here's a proof:

lemma sset_cycle [simp]:
  assumes "xs ≠ []"
  shows   "sset (cycle xs) = set xs"
proof
  have "set xs ⊆ set xs ∪ sset (cycle xs)" by blast
  also have "… = sset (xs @- cycle xs)" by simp
  also from ‹xs ≠ []› have "xs @- cycle xs = cycle xs" 
    by (rule cycle_decomp [symmetric])
  finally show "set xs ⊆ sset (cycle xs)" .
next
  from assms have "cycle xs !! n ∈ set xs" for n
  proof (induction n arbitrary: xs)
    case (Suc n xs)
    have "tl xs @ [hd xs] ≠ []" by simp
    hence "cycle (tl xs @ [hd xs]) !! n ∈ set (tl xs @ [hd xs])" by (rule Suc.IH)
    also have "cycle (tl xs @ [hd xs]) !! n = cycle xs !! Suc n" by simp
    also have "set (tl xs @ [hd xs]) = set (hd xs # tl xs)" by simp
    also from ‹xs ≠ []› have "hd xs # tl xs = xs" by simp
    finally show ?case .
  qed simp_all
  thus "sset (cycle xs) ⊆ set xs" by (auto simp: sset_range)
qed

UPDATE: The following proof is a bit nicer:

lemma sset_cycle [simp]:
  assumes "xs ≠ []"
  shows   "sset (cycle xs) = set xs"
proof
  have "set xs ⊆ set xs ∪ sset (cycle xs)" by blast
  also have "… = sset (xs @- cycle xs)" by simp
  also from ‹xs ≠ []› have "xs @- cycle xs = cycle xs" 
    by (rule cycle_decomp [symmetric])
  finally show "set xs ⊆ sset (cycle xs)" .
next
  show "sset (cycle xs) ⊆ set xs"
  proof
    fix x assume "x ∈ sset (cycle xs)"
    from this and ‹xs ≠ []› show "x ∈ set xs"
    proof (induction "cycle xs" arbitrary: xs)
      case (stl x xs)
      have "x ∈ set (tl xs @ [hd xs])" by (intro stl) simp_all
      also have "set (tl xs @ [hd xs]) = set (hd xs # tl xs)" by simp
      also from ‹xs ≠ []› have "hd xs # tl xs = xs" by simp
      finally show ?case .
    qed simp_all
  qed
qed
Manuel Eberl
  • 7,858
  • 15
  • 24
2

Instead of induction over n and using op !! as proposed by Manuel Eberl you can also do induction directly over sset (with rule sset_induct):

lemma sset_cycle [simp]:
  assumes "xs ≠ []" 
  shows "sset (cycle xs) = set xs"
proof (intro set_eqI iffI)
  fix x
  assume "x ∈ sset (cycle xs)"
  from this assms show "x ∈ set xs"
    by (induction "cycle xs" arbitrary: xs rule: sset_induct) (case_tac xs; fastforce)+
next
  fix x
  assume "x ∈ set xs"
  with assms show "x ∈ sset (cycle xs)"
   by (metis UnI1 cycle_decomp sset_shift)
qed
Denis
  • 530
  • 2
  • 7