// RUN: %dafny /compile:0 /dprint:"%t.dprint" "%s" > "%t" // RUN: %diff "%s.expect" "%t" // ------------------ generic list, non-generic tree datatype List = Nil | Cons(T, List) datatype Tree = Node(int, List) function Inc(t: Tree): Tree { match t case Node(n, children) => Tree.Node(n+1, ForestInc(children)) } function ForestInc(forest: List): List { match forest case Nil => forest case Cons(tree, tail) => List.Cons(Inc(tree), ForestInc(tail)) } // ------------------ generic list, generic tree (but GInc defined only for GTree datatype GTree = Node(T, List>) function GInc(t: GTree): GTree { match t case Node(n, children) => GTree.Node(n+1, GForestInc(children)) } function GForestInc(forest: List>): List> { match forest case Nil => forest case Cons(tree, tail) => List.Cons(GInc(tree), GForestInc(tail)) } // ------------------ non-generic structures datatype TreeList = Nil | Cons(OneTree, TreeList) datatype OneTree = Node(int, TreeList) function XInc(t: OneTree): OneTree { match t case Node(n, children) => OneTree.Node(n+1, XForestInc(children)) } function XForestInc(forest: TreeList): TreeList { match forest case Nil => forest case Cons(tree, tail) => TreeList.Cons(XInc(tree), XForestInc(tail)) } // ------------------ fun with recursive functions function len(l: List): int { match l case Nil => 0 case Cons(h,t) => 1 + len(t) } function SingletonList(h: T): List ensures len(SingletonList(h)) == 1; { List.Cons(h, List.Nil) } function Append(a: List, b: List): List ensures len(Append(a,b)) == len(a) + len(b); { match a case Nil => b case Cons(h,t) => List.Cons(h, Append(t, b)) } function Rotate(n: int, l: List): List requires 0 <= n; ensures len(Rotate(n, l)) == len(l); { match l case Nil => l case Cons(h, t) => if n == 0 then l else Rotate(n-1, Append(t, SingletonList(h))) }