2
votes

I have trouble with these proofs that seem almost trivially obvious.

For instance, in the inductive case if I assume the property in the title and I want to show:

length (h'::h::l) = 1 + length (h::l)

Where do I go from here? It is so obviously true but I don't know what steps I can take without proving some kind of lemma. For instance I could say

length ([h']@(h::l)) = 1 + length (h::l)

But now I have to prove something along the lines of

length (l1@l2) = length l1 + length l2

I'm having trouble understanding when I need to prove lemmas, especially in the proofs that seem almost trivial.

2
I'm voting to close this question as off-topic because it's a math question, not a programming question.wvdz
It's related to a programming course and its a proof of a program in ocaml. I disagree.Connor
@wvdz see Type Theory: propositions are types, proofs are programs. Maybe add a Coq tag.Str.

2 Answers

2
votes

When you prove program correctness, you're usually working with some implementation. If you will take a trivial implementation, then the proof would be also trivial. Suppose we have the following implementation:

let rec length = function
  | [] -> 0
  | x::xs -> 1 + length xs

We have a proof obligation:

length (x::xs) = 1 + length xs

We proof this using structural induction. I'm assuming, that list is defined as

type 'a list = 
  | Nil 
  | Cons ('a,'a list)

and [] is a syntactic sugar for Nil, while x::xs is a syntactic sugar for Cons (x,xs)

So we perform case by case analysis. We have only one applicable case, so we take case

  | x::xs -> 1 + length xs

rewrite length (x::xs) with the right hand side, and we get:

  1 + legnth xs = 1 + length xs

This can be proven by reflexivity of = operator. (If it is reflexive in your logic).

Note: the above implementation is trivial. In OCaml standard library List.length is implemented as follows:

let rec length_aux len = function
    [] -> len
  | a::l -> length_aux (len + 1) l

let length l = length_aux 0 l

Here proof obligation length (x::xs) = 1 + length xs produces an obligation to proof that length_aux 0 (x::xs) = 1 + length_aux 0 xs. This is less trivial.

1
votes

I would say first, that length is defined by induction, length of void is 0, and length(h::l) = 1 + length(l).

Then, concatenation is defined also by induction, []@l=l, and [h]@l = h::l.

length is a function that maps @ to + : the proof is an induction proof using above properties. You proceed by induction on l1 : the property length(l1@l2) = length(l1)+length(l2) when l1 is empty (induction axiom). Then assuming the property is right with for l1 of length n, you want to prove it is correct for n+1. length(h::l1@l2) = 1 + length(l1@l2) (thx to length definition). Then by induction hypothesis, you length(l1@l2) = length(l1)+length(l2), you conclude.