// Defining lists and some operations on them datatype List = Nil | Cons(head: T, tail: List) function Snoc(xs: List, y: T): List { match xs case Nil => Cons(y, Nil) case Cons(x, tail) => Cons(x, Snoc(tail, y)) } function Append(xs: List, ys: List): List { match xs case Nil => ys case Cons(x, tail) => Cons(x, Append(tail, ys)) } function ReverseAux(xs: List, acc: List): List { match xs case Nil => acc case Cons(x, tail) => ReverseAux(tail, Cons(x, acc)) } function SlowReverse(xs: List): List { match xs case Nil => Nil case Cons(x, tail) => Snoc(SlowReverse(tail), x) } // Lemmas you'll likely find helpful lemma AppendAssociative(xs: List, ys: List, zs:List) ensures Append(Append(xs, ys), zs) == Append(xs, Append(ys, zs)) { } lemma SnocAppend(xs: List, y: T) ensures Snoc(xs, y) == Append(xs, Cons(y, Nil)) { } // The lemma for you to prove lemma ReverseAuxSlowCorrect(xs: List, acc: List) ensures ReverseAux(xs, acc) == Append(SlowReverse(xs), acc) { match xs case Nil => case Cons(x, tail) => calc { Append(SlowReverse(xs), acc); == ReverseAux(xs, acc); } // Extend this proof to pass Dafny checking. }