IndProp2: Inductively Defined PropositionsInductiver and Propisitionier

Overview

We'll continue our discussion of inductive propositions, started in IndProp. We'll introduce several new inductive propositions that we'll be using in this and Sort, the next chapter.
Our bioinformatics case study will come to its thrilling conclusion where we prove that Levenshtein edit distance is optimal (i.e., produces edits of minimal cost).

Set Warnings "-notation-overridden,-parsing".
From DMFP Require Export IndProp.

Doing it yourself

Exercise: 3 stars, standard (nostutter_defn)

Formulating inductive definitions of properties is an important skill you'll need in any formal work in computer science. Try to solve this exercise without any help at all.
We say that a list "stutters" if it repeats the same element consecutively. (This is different from the NoDup property in the exercise above: the sequence 1;4;1 repeats but does not stutter.) The property "nostutter mylist" means that mylist does not stutter. Formulate an inductive definition for nostutter.

Inductive nostutter {X:Type} : list X Prop :=
(* FILL IN HERE *)
.
Make sure each of these tests succeeds, but feel free to change the suggested proof (in comments) if the given one doesn't work for you. Your definition might be different from ours and still be correct, in which case the examples might need a different proof. (You'll notice that the suggested proofs use a number of tactics we haven't talked about, to make them more robust to different possible ways of defining nostutter. You can probably just uncomment and use them as-is, but you can also prove each example with more basic tactics.)

Example test_nostutter_1: nostutter [3;1;4;1;5;6].
(* FILL IN HERE *) Admitted.
(* 
Proof. repeat constructor; apply eqb_false_iff; auto.
Qed.
*)


Example test_nostutter_2: nostutter (@nil nat).
(* FILL IN HERE *) Admitted.
(* 
Proof. repeat constructor; apply eqb_false_iff; auto.
Qed.
*)


Example test_nostutter_3: nostutter [5].
(* FILL IN HERE *) Admitted.
(* 
Proof. repeat constructor; apply eqb_false; auto. Qed.
*)


Example test_nostutter_4: not (nostutter [3;1;1;4]).
(* FILL IN HERE *) Admitted.
(* 
Proof. intro.
       repeat match goal with
                h: nostutter _ ⊢ _ => inversion h; clear h; subst
              end.
       contradiction; auto. Qed.
*)

(* Do not modify the following line: *)
Definition manual_grade_for_check_nostutter_def : option (nat×string) := None.

Exercise: 2 stars, advanced (subseq)

A list is a subsequence of another list if all of the elements in the first list occur in the same order in the second list, possibly with some extra elements in between. For example,
      [1;2;3]
is a subsequence of each of the lists
      [1;2;3]
      [1;1;1;2;2;3]
      [1;2;7;3]
      [5;6;1;9;9;2;7;3;8]
but it is not a subsequence of any of the lists
      [1;2]
      [1;3]
      [5;6;2;1;7;3;8].
  • Define an inductive proposition subseq on list nat that captures what it means to be a subsequence. (Hint: You'll need three cases.)
  • Prove subseq_refl that subsequence is reflexive, that is, any list is a subsequence of itself.
  • Prove subseq_app that for any lists l1, l2, and l3, if l1 is a subsequence of l2, then l1 is also a subsequence of l2 ++ l3.

Inductive subseq : list nat list nat Prop :=
(* FILL IN HERE *)
.

Theorem subseq_refl : (l : list nat), subseq l l.
Proof. (* FILL IN HERE *) Admitted.

Theorem subseq_app : (l1 l2 l3 : list nat),
    subseq l1 l2
    subseq l1 (l2 ++ l3).
Proof. (* FILL IN HERE *) Admitted.

Exercise: 2 stars, advanced, optional (subseq_trans)

Theorem subseq_trans : (l1 l2 l3 : list nat),
    subseq l1 l2
    subseq l2 l3
    subseq l1 l3.
Proof. (* FILL IN HERE *) Admitted.

Exercise: 4 stars, standard, optional (palindromes)

A palindrome is a sequence that reads the same backwards as forwards.
  • Define an inductive proposition pal on list X that captures what it means to be a palindrome. (Hint: You'll need three cases. Your definition should be based on the structure of the list; just having a single constructor like
            c : l, l = rev lpal l
    may seem obvious, but will not work very well.)
  • Prove (pal_app_rev) that
            l, pal (l ++ rev l).
  • Prove (pal_rev that)
            l, pal ll = rev l.

(* FILL IN HERE *)
(* Do not modify the following line: *)
Definition manual_grade_for_pal_pal_app_rev_pal_rev : option (nat×string) := None.

Exercise: 5 stars, standard, optional (palindrome_converse)

Again, the converse direction is significantly more difficult, due to the lack of evidence. Using your definition of pal from the previous exercise, prove that
      l, l = rev lpal l.

(* FILL IN HERE *)

(* Mon Apr 6 09:16:56 PDT 2020 *)