2

Since multi-way trees can be defined as a recursive type:

data RoseTree a = Node {leaf :: a, subTrees :: [RoseTree a]}

is there a corresponding principle for performing structural induction on this type?

Rich Ashworth
  • 1,995
  • 4
  • 19
  • 29
  • 2
    You mean like `Foldable` and `Traversable`? Using `-XDeriveFunctor`, `DeriveFoldable`, `DeriveTraversable` and `import Data.Foldable` and `import Data.Traversable` you can `derive (Functor, Foldable, Traversable)` on `RoseTree` to get a generic `fold` and `traverse` for it. – bheklilr Mar 24 '15 at 13:26
  • Thanks. I was really asking in terms of reasoning about the structures (as described in http://en.wikipedia.org/wiki/Structural_induction), rather than doing anything with the trees themselves. – Rich Ashworth Mar 24 '15 at 13:29
  • @RichAshworth I find your question unclear. If you're not interested in declaring a `Foldable` or `Traversable` instance for your tree and all you want is to reason about the (abstract) data structure, why show a Haskell implementation of it? – jub0bs Mar 24 '15 at 13:46
  • Haskell implementation included so that this thread has a common language for talking about rose trees (I have come across a number of ways these can be represented). Agree this isn't really related to Haskell programming. – Rich Ashworth Mar 24 '15 at 14:41

1 Answers1

3

To state that property P holds for all (*) rose trees, you have to prove that

  • if l :: [RoseTree] is a list of rose trees whose elements satisfy P, and x :: a is arbitrary, then Note x l satisfies P

The part about P holding on the elements of l is the induction hypothesis, which you can use to prove P(Node x l).

There is no explicit base case here: this is because there's no explicit base case constructor. Yet, Node x [] acts as an implicit base case for the trees, and indeed when l is empty we get a base case for induction implicitly. Concretely, the hypothesis "all the elements of l satisfy P" becomes vacuously true when l is empty, so we get P(Node x []) from the induction principle above.

(*) More precisely, this principle proves P for every finite-depth rose tree. If you really have to consider infinite-depth ones (e.g. circular trees), you need coinduction.

chi
  • 111,837
  • 3
  • 133
  • 218
  • Could you point me to an explanation of coinduction? Or explain it yourself? – dfeuer Mar 24 '15 at 14:47
  • @dfeuer The topic is quite broad. To get an overview you can check wikipedia for it, corecursion, (Knaster-)Tarski's theorem, greatest fixed points, and final coalgebras. Also, bisimilarity between processes in a process algebra is a typical notion which involves proofs by coinduction. In the specific context of functional programming and codata, I guess it can be used, but I can't point to a typical example. – chi Mar 24 '15 at 14:59
  • 2
    @dfeuer Andy's brilliant paper from 1994 is the canonical reference for co-induction in FP, and it is highly readable: http://marcellodesales-cs-research.googlecode.com/svn/trunk/ms-cs-ufcg-brazil/functional-programming/docs/gordon94tutorial.pdf Note that in the context of Haskell, it essentially amounts to proving P(bottom) holds, since data and co-data are the same in Haskell. – alias Mar 25 '15 at 05:13
  • could you point me to an example of induction being used like this? in the literature, I have only seen proofs using binary trees – Rich Ashworth Jun 19 '15 at 14:25