In this session we come back to the problem of proving properties about

programs. Where before, we covered just lists, we

will now look at more job data structures, Maybe trees.

Remember in the intro to this course, I told you that functional programming is

important because it's very close to the mathematical theories of data structures.

We put that to a test. Now we will develop such a theory for

integer sets and prove an implementation correct with respect to the theory.

As was the case in the previous proving sessions, the material in this session is

optional for the online class. If you're a student of the Life EPFL

class, you should follow the material, because it might be relevant for the exam.

But we can generalize the structural induction principal for lists to arbitrate

these structures. The principal then becomes the following.

We want to prove a property P of T for all trees of a certain type What we need to do

to do that, is we need to show that P of L holds for all leaves types of the tree.

And for each type of internal node T which has let's say sub-trees as one, two SN, we

need to show that under the assumption that PS1 and PSN all the sub, all the

sub-trees satisfy the predicate than P of T holds.

So let's use this proof technique to show some interesting facts about IntSet.

We call our definition of IntSets from previous sessions.

We had an abstract class IntSet with operation include and contains, and then

we had two different implementations. Once was, one was an object empty and the

other was the class nonempty, and there was an invariant.

We assume then that was that the elements in a tree were ordered.

That means that the left subtree of any nonempty tree contained elements that were

smaller, or smaller than the current element.

And the right subtree contained elements that were larger.

And our implementations of contains and include made use of that invariant.

So we would like to prove that implementation of IntSet correct.

But what does it even mean? What do we mean by, by proving the

correctness of an IntSet implementation? Well, one way to define correctness would

be to define some laws that our implementation should just, should

satisfy, and then prove that the implementation indeed does that.

So in the case of IntSet, what laws could we come up with?

The first law says the empty set does not contain any, any element so empty contains

x is always false. The second law says that if we add an

element x to a set, an arbitrary set and then ask whether the set contains x, then

we are certain that we will get back true. And the third law says that if we add an

element x to a set and then ask whether the set contains some other element y.

Then the answer is the same thing as simply S contains Y.

So, it didn't matter the fact whether we added X or not.

The answer will be invariant under that. In fact, one can show that these three

laws completely characterize what it is, to be an n set.

So, the, we have now an algebraic specification of IntSet which is complete.

But it still remains how to prove these laws.

So, let's start with the first one. Empty contains x equal false.

Well that one is actually easy because that's a direct consequence of the

definition of contains and empty. Have a quick look at it, so here you see

empty contains any element would give us false.

The second proposition says that if we include X and S and then ask, whether the

set contains X, we would get true. And that we can prove by a structure

induction on the set S. The base case would be the set S is empty,

so we are left with the expression, empty include X contains X.

Now, empty include X, we know what that is, by the rule of empty.include.

That would give us a nonempty set X with two empty subsets, and we ask whether that

one contains X. And, the answer here is true because of

the clause of, contains in a nonempty set where we know that if we ask for the

element at the top of the tree then the answer is True.

We can compare to the implementation of nonempty to verify that.

So that was the base case. What about the induction step?

So the induction step would be that we have a tree, call it nonempty.