0

In the excellent Programming and Proving in Isabelle/HOL it says

[...] in contrast to recursive functions, there is no termination requirement for inductive definitions. (pdf p. 40)

  1. Does this mean there are inductive definitions where it's possible to have an infinitely deep derivation tree?
  2. What is an example of such a non-terminating derivation (preferably one with infinite height)? How do you 'construct' these?
  3. How are rule induction principles on these still sound?
Sebastian Graf
  • 3,602
  • 3
  • 27
  • 38

2 Answers2

2
  1. No. You need coinductive predicates for that.
  2. Not existing.
  3. If you look at the induction principle, you'll find that they have an additional premise. For example, "even n". That means, before you can even apply the induction principle, you'll need to know that you have a finite derivation at hand.
Manuel Eberl
  • 7,858
  • 15
  • 24
larsrh
  • 2,579
  • 8
  • 30
  • Thanks. I'm familiar with coinduction (at least from a programmatic point of view). But what does '**in contrast to** recursive functions, there is no termination requirement for inductive definitions' mean then? E.g. if there is no way to diverge, why bother saying that? I guess it's about the difference to `function` and supplying explicit termination proofs, but I'm not sure. – Sebastian Graf Apr 28 '17 at 09:07
  • If you use `function` and don't supply a termination proof, you get basically the same result. All rules (induction, simplification) have a similar additional assumption. – larsrh Apr 28 '17 at 10:18
  • When you have e.g. the semantics of a programming language with loops, you can write down its semantics as an `inductive` (program `p` run on state `s` terminates in state `s'`), but you cannot easily write it down with `function` because of the possible non-termination. One way to look at it is that `inductive` gives you the result `false` for non-termination ‘for free’, whereas if you wrote a function doing the same thing, you would have to recognise these cases yourself and actively return `false`. – Manuel Eberl Apr 28 '17 at 12:35
2

Lars already answered the question, but I would like to expand on the coinductive predicates he mentioned. These indeed allow you to have ‘infinitely deep derivation trees’, corresponding to how codatatypes are essentially ‘possibly infinite datatypes’.

A good example is the stream type from ~~/src/HOL/Library/Stream:

codatatype 'a stream = SCons 'a "'a stream" (infixr "##" 65)

This is an infinite list (note that unlike e.g. Haskell lists, this stream type has to be infinitely long, like if you wrote datatype Stream a = SCons a (Stream a) in Haskell, although Haskell-style ‘potentially infinite’ lists are also possible straightforward, cf. the lazy lists in the AFP)

You can then e.g. define the set of all streams whose values are from a given set. You could define that as streams A = {s. sset s ⊆ A}, but in Isabelle, it is defined coinductively like this:

coinductive_set streams :: "'a set ⇒ 'a stream set" for A :: "'a set"
  where "⟦a ∈ A; s ∈ streams A⟧ ⟹ a ## s ∈ streams A"

Another, perhaps easier example, would be a coinductive ‘for all elements’ predicate on streams:

coinductive sall :: "('a ⇒ bool) ⇒ 'a stream ⇒ bool" for P :: "'a ⇒ bool" where
  "P x ⟹ sall P xs ⟹ sall P (x ## xs)"

As for the question of how to construct such an infinite derivation tree, i.e. showing that a coinductive predicate holds on some value, you have to do that with coinduction. E.g. we can show that if P x holds, then sall P (sconst x) holds, where sconst x is just the value x repeated infinitely:

lemma sconst_reduce: "sconst x = x ## sconst x"
  by (subst siterate.code) simp_all

lemma sall_sconst: "P x ⟹ sall P (sconst x)"
proof (coinduction rule: sall.coinduct)
  assume "P x"
  thus "∃y ys. sconst x = y ## ys ∧ P y ∧ (ys = sconst x ∧ P x ∨ sall P ys)"
    by (subst sconst_reduce) auto
qed
Manuel Eberl
  • 7,858
  • 15
  • 24