(* To be finished for Saturday midnight -- at least "Main topic" Solutions of "Main topic" will then provided with additional material *) (* ============================================================ *) (* A SPECIFICATION IS RELATION BETWEEN INPUTS AND OUTPUT *) (* ============================================================ *) (* ------------------------------------------------------------ *) (* WARMING UP *) (* Here is a simple example: greatest common divisor between 2 natural numbers *) (* We need auxiliary definitions *) Definition divides (n m: nat): Prop := exists d, n * d = m. Definition is_common_div (n:nat) (m: nat) (cd: nat): Prop := divides cd n /\ divides cd m. (* Now we specify that the gcd [g] of [n] and [m] - is a common divisor of [n] and [m] - is greater than any other common divisor of [n] and [m] *) Definition spec_gcd (n:nat) (m: nat) (g: nat): Prop := is_common_div n m g /\ (forall x, is_common_div n m x -> x <= g). (* Now we could propose a function [gcd] and prove that it satisfies tha above specification *) Fixpoint gcd (n m: nat) : nat. (* NO NEED TO FILL IN HERE! *) Admitted. Theorem gcd_correct: forall n m, spec_gcd n m (gcd n m). Proof. (* NO NEED TO FILL IN HERE! *) Admitted. (* ----------------------------------- *) (* Another simple example: predecessor of a natural number *) Definition spec_pred_first_attempt (n:nat) (p: nat): Prop := n = (S p). (* This specification is wrong because it *enforces* the input [n] to be non-zero, whereas only total functions can be defined. The right specification should then be weakened as follows: *) Definition spec_pred (n:nat) (p: nat): Prop := n <> 0 -> n = (S p). (* Now we can prove: *) Theorem pred_correct: forall n, spec_pred n (pred n). Proof. (* FILL IN HERE *) Admitted. (* ----------------------------------- *) (* Another approach to the predecessor *) (* Instead of considering the standard [pred: nat -> nat] consider a [ppred: forall n, positive n -> nat] *) Definition positive (n: nat) := match n with O => False | _ => True end. (* Then the specification has 3 arguments (2 inputs and 1 output) *) Definition spec_ppred (n: nat) (Pn: positive n) (p: nat) := n = S p. (* The definition of [ppred] is more complicated *) Definition ppred_interactive (n:nat) (Pn: positive n) : nat. destruct n as [ | p]; simpl in Pn. case Pn. exact p. Defined. Definition ppred (n:nat) (Pn: positive n) : nat := match n return positive n -> nat with | 0 => fun F => match F with end | S p => fun _ => p end Pn. Theorem ppred_correct: forall n Pn, spec_ppred n Pn (ppred n Pn). Proof. (* FILL IN HERE *) Admitted. (* ------------------------------------------------------------ *) (* MAIN TOPIC *) (* Finding the minimum element in a list *) Section sec_min. Variable A : Set. Variable default : A. (* comparison : R x y means x less or equal to y *) Variable R : A -> A -> Prop. (* Some properties of R? *) Hypothesis refl: forall x, R x x. Hypothesis total : forall x y, R x y \/ R y x. (* choice 1 for comparison pgm *) Variable bool_comp : A -> A -> bool. Hypothesis bool_comp1: forall x y, bool_comp x y = true -> R x y. Hypothesis bool_comp2: forall x y, bool_comp x y = false -> R y x. (* choice 2 for comparison pgm *) Variable comp : forall x y, {R x y}+{R y x}. Inductive list : Set := | nil : list | cons : A -> list -> list. (* ------------------------------------------------------------ *) (* Informal expectations: - the result is in A - have a list l as a parameter of find_min - the result is a member of l ===> define member - the result is less or equal (R) to all members of l *NO "other" ---> reflexivity of R *) (* Draft Definition find_min (l : list) : A := *) (* Draft thoughts You can put here informal ideas, unfinished statements etc. member : A -> list -> Prop forall l : list, m : A forall x:A, member x l -> R m x *) (* Define member *) (* FILL IN HERE *) (* Other auxiliary predicates ? *) (* FILL IN HERE *) (* Specification of the expected result of [find_min] *) (* The following relation should express expected constraints between the input [l] and the result [m] *) Definition spec_find_min (l: list) (m: A) : Prop. (* FILL IN HERE *) Admitted. (* If your specification is right, it should be for a partial function... *) End sec_min.