Objectif du TP
Verifier formellement en Coq les proprietes du langage MusicFunk concu dans le TP1 : le retrograde est une involution, la transposition conserve le nombre de notes, l'augmentation multiplie la duree.
Lien avec le cours
Tester qu'un programme fonctionne, c'est bien ; prouver qu'il fonctionne toujours, c'est mieux !
Partie A — Representation Coq des melodies (1h)
Types de donnees
(* Les notes de la gamme *)
Inductive note : Type :=
| C | D | E | F | G | A | B.
(* Une melody est un arbre inductif *)
Inductive melody : Type :=
| Silence : nat -> melody
| Note : note -> nat -> melody
| Seq : melody -> melody -> melody
| Rep : melody -> nat -> melody.
Simplification
La duree est un nat (nombre de noires) au lieu d'un float.
Cette simplification rend les preuves plus accessibles.
Fonctions de base
Fixpoint duree_totale (m : melody) : nat :=
match m with
| Silence d => d
| Note _ _ => 1
| Seq m1 m2 => duree_totale m1 + duree_totale m2
| Rep m n => n * duree_totale m
end.
Fixpoint nb_notes (m : melody) : nat :=
match m with
| Silence _ => 0
| Note _ _ => 1
| Seq m1 m2 => nb_notes m1 + nb_notes m2
| Rep m n => n * nb_notes m
end.
Partie B — Preuves des transformations (1.5h)
Transposition preserve le nombre de notes
Fixpoint transpose_nat (st : nat) (m : melody) : melody :=
match m with
| Silence d => Silence d
| Note n o => Note n o
| Seq m1 m2 => Seq (transpose_nat st m1) (transpose_nat st m2)
| Rep m n => Rep (transpose_nat st m) n
end.
Lemma transpose_preserves_notes : forall st m,
nb_notes (transpose_nat st m) = nb_notes m.
Proof.
intros st m.
induction m as [| n o | m1 IH1 m2 IH2 | m n IH].
- simpl. reflexivity.
- simpl. reflexivity.
- simpl. rewrite IH1. rewrite IH2. reflexivity.
- simpl. rewrite IH. reflexivity.
Qed.
Retrograde est une involution
Fixpoint retrograde (m : melody) : melody :=
match m with
| Silence d => Silence d
| Note n o => Note n o
| Seq m1 m2 => Seq (retrograde m2) (retrograde m1)
| Rep m n => Rep (retrograde m) n
end.
Lemma retrograde_involutive : forall m,
retrograde (retrograde m) = m.
Proof.
intro m.
induction m as [| n o | m1 IH1 m2 IH2 | m n IH].
- simpl. reflexivity.
- simpl. reflexivity.
- simpl. rewrite IH1. rewrite IH2. reflexivity.
- simpl. rewrite IH. reflexivity.
Qed.
Augmentation multiplie la duree
Fixpoint augmenter (k : nat) (m : melody) : melody :=
match m with
| Silence d => Silence (k * d)
| Note n o => Note n o
| Seq m1 m2 => Seq (augmenter k m1) (augmenter k m2)
| Rep m n => Rep (augmenter k m) n
end.
Lemma augmenter_duree : forall k m,
duree_totale (augmenter k m) = k * duree_totale m.
Proof.
intros k m.
induction m as [| n o | m1 IH1 m2 IH2 | m n IH].
- simpl. lia.
- simpl. lia.
- simpl. rewrite IH1. rewrite IH2. lia.
- simpl. rewrite IH. lia.
Qed.
Partie C — Proprietes de composition (0.5h)
(* Silence 0 est l'element neutre de Seq *)
Lemma seq_nil_r : forall m,
Seq m (Silence 0) = m.
Proof.
intro m. reflexivity.
Qed.
(* Repeter 1 fois = identite *)
Lemma rep_1 : forall m,
Rep m 1 = m.
Proof.
intro m. reflexivity.
Qed.
(* nb_notes est additif sur Seq *)
Lemma nb_notes_seq : forall m1 m2,
nb_notes (Seq m1 m2) = nb_notes m1 + nb_notes m2.
Proof.
intros m1 m2. reflexivity.
Qed.
Partie D — Proprietes avancees (1h)
(* Retrograde preserve la duree totale *)
Lemma retrograde_preserves_duree : forall m,
duree_totale (retrograde m) = duree_totale m.
Proof.
intro m.
induction m as [| n o | m1 IH1 m2 IH2 | m n IH].
- simpl. reflexivity.
- simpl. reflexivity.
- simpl. rewrite IH1. rewrite IH2. lia.
- simpl. rewrite IH. lia.
Qed.
(* Retrograde preserve le nombre de notes *)
Lemma retrograde_preserves_notes : forall m,
nb_notes (retrograde m) = nb_notes m.
Proof.
intro m.
induction m as [| n o | m1 IH1 m2 IH2 | m n IH].
- simpl. reflexivity.
- simpl. reflexivity.
- simpl. rewrite IH1. rewrite IH2. lia.
- simpl. rewrite IH. lia.
Qed.
Synthese
| Propriete | Lemme Coq | Preuve |
|---|---|---|
| Transposition conserve nb_notes | transpose_preserves_notes | induction |
| Retrograde est une involution | retrograde_involutive | induction |
| Augmentation multiplie la duree | augmenter_duree | induction + lia |
| Repetition 1 = identite | rep_1 | reflexivite |
| Duree additive sur Seq | duree_seq | reflexivite |
| Retrograde preserve duree | retrograde_preserves_duree | induction + lia |
| Retrograde preserve notes | retrograde_preserves_notes | induction + lia |
Rendu
Le fichier music_funk.v contenant toutes les definitions et preuves.
Chaque theoreme doit etre accepte par Coq (pas de Admitted).