Set the syntax to be Coq in the post

This commit is contained in:
Danila Fedorin 2019-08-13 21:32:05 -07:00
parent fce8e75dde
commit fe0437eabf

View File

@ -14,7 +14,7 @@ Of course, my definition led to only having palindromes of even length. In order
* A list with a single value is a palindrome.
This translates readily into Coq:
```
```Coq
Inductive palindrome { X : Type } : list X -> Prop :=
| palindrome_nil : palindrome []
| palindrome_x : forall (x : X), palindrome [x]
@ -24,7 +24,7 @@ Inductive palindrome { X : Type } : list X -> Prop :=
### The first direction
Its nearly trivial to show that a palindrome is its own inverse:
```
```Coq
Theorem pal_rev { X : Type } : forall (l : list X), palindrome l -> l = rev l.
Proof.
intros l H.
@ -49,7 +49,7 @@ Then, the proposition holds for all values of that type. This can be easily seen
As I was working with my definition of a palindrome, it dawned on me that generalizing a single variable in that definition would create another inductive definition of a list. If we change the inductive rule in the palindrome definition from saying “surrounding another palindrome with x on both sides” to “surrounding another list with some x on one side and some y on the other”, we can effectively construct any list. We can then state a different structural induction principle:
```
```Coq
Theorem alt_induction { X : Type } : forall (P : list X -> Prop),
P [] ->
(forall (x : X), P [x]) ->
@ -61,7 +61,7 @@ But how would we go about proving this? If we try to just use induction on `ln`,
#### Proving Equivalence
Whats missing is that theres nothing as yet stating that appending values to the back and the front of another list is an equivalent way to appending a value only to the front of a list. We need to state this explicitly; but how? I decided that the easiest way would be by defining a new inductive property, `list_alt` which holds for all lists that can be constructed by adding things to the back and the front. Then, we can show that it holds for all lists, and, therefore, that any list can be constructed this way. I defined the property as such:
```
```Coq
Inductive list_alt { X : Type } : list X -> Prop :=
| list_alt_base : list_alt []
| list_alt_x : forall (x : X), list_alt [x]
@ -70,7 +70,7 @@ Inductive list_alt { X : Type } : list X -> Prop :=
Then, to prove it true for all lists, I first showed what is effectively the inductive hypothesis of a proof by induction on the structure of a list:
```
```Coq
Theorem list_alt_cons { X : Type } : forall (x : X) (l : list X),
list_alt l -> list_alt (x::l).
Proof.
@ -91,7 +91,7 @@ Qed.
```
Next, the actual proof of equivalence simply used the previous theorem:
```
```Coq
Theorem list_alt_correct { X : Type } : forall (l : list X), list_alt l.
Proof.
induction l.
@ -102,7 +102,7 @@ Qed.
Finally, we can prove our custom principle of induction (by induction (!) on the property list_alt, which we now know holds for all lists):
```
```Coq
Theorem alt_induction { X : Type } : forall (P : list X -> Prop),
P [] ->
(forall (x : X), P [x]) ->
@ -118,7 +118,7 @@ Proof.
Finally, the palindrome proof can simply use this principle. Coq turns out to have a mechanism to use a custom induction principle via `induction … using …`:
```
```Coq
Theorem rev_pal' { X : Type } : forall (l : list X), l = rev l -> palindrome l.
Proof.
intros l H. induction l using alt_induction.