Lists
Table of Contents
- 1. Summary
- 2. Notes
- 3. Exercises
- 3.1.
snd_fst_is_swap
- 3.2.
fst_swap_is_snd
- 3.3.
list_funs
- 3.4.
alternate
- 3.5.
bag_functions
- 3.6.
remove_one
- 3.7.
remove_all
- 3.8.
included
- 3.9.
add_inc_count
- 3.10.
eqblist
- 3.11.
count_member_nonzero
- 3.12.
count_member_n_nonzero
- 3.13.
remove_does_not_increase_count
- 3.14.
bag_count_sum
- 3.15.
involution_injective
- 3.16.
rev_injective
- 3.17.
hd_error
- 3.18.
option_elim_hd
- 3.19.
eqb_id_refl
- 3.20. =updateeq
- 3.21. updateneq
- 3.1.
- 4. Scores
- 5. Questions
- 6. Metacognition
- 7. Further Knowledge
- 8. TODOs
Homepage | Previous: Induction | Code | Next: Polymorphism
1. Summary
This chapter introduces foundational proof techniques in Coq using lists, pairs, and basic functional programming constructs.
1.1. Terms
Search
, pairs, lists, partial maps, options, bags.
2. Notes
2.1. Pairs of Numbers
- Defined an inductive type
natprod
for pairs of numbers. - Introduced proofs using
destruct
and simplification.- Example: Proved surjective pairing by destructing pairs into components.
2.2. Lists of Numbers
- Introduced the inductive type
natlist
for lists of natural numbers. - Examples of recursive functions:
length
: Calculate the length of a list.app
: Append two lists.nonzeros
: Filter out zeros from a list.
Proof Techniques:
- Induction:
- Used induction over lists for proofs.
- Example: Proved
app_assoc
(associativity of list append) using list induction.
- Case Analysis:
- Example: Proved
tl_length_pred
by analyzing whether the list is empty or non-empty.
- Example: Proved
2.3. Generalizing Statements
- Demonstrated generalizing theorems for stronger inductive hypotheses.
- Example: Proved
repeat_plus
for generalized sums of repeated lists.
- Example: Proved
2.4. Reversing a List
- Defined
rev
, a function to reverse lists. - Proved properties of
rev
:rev_length
: Reversing a list does not change its length.rev_involutive
: Reversing a list twice gives the original list.
- Key Proof Techniques:
- Leveraging helper lemmas such as
app_length
. - Structuring proofs with auxiliary results when stuck.
- Leveraging helper lemmas such as
2.5. Bags (Multisets)
- Introduced bags as lists with additional functions:
count
: Count occurrences of an element.sum
: Combine two bags.add
: Add an element to a bag.member
: Check if an element exists in a bag.
- Proof Techniques:
- Direct reasoning with destruct.
- Example: Proved
add_inc_count
(adding increases count) by case analysis.
2.6. Reasoning About Lists
- Explored techniques for proving list properties:
- Example:
rev_app_distr
: Proved that reversing an appended list distributes over the append. - Used helper theorems (
app_assoc
,app_length
) for modular reasoning.
- Example:
2.7. Options
- Introduced
natoption
to handle partial functions safely. - Defined functions like
nth_error
andhd_error
for lists with proper error handling. - Proved equivalence between implementations:
- Example: Related
hd_error
to an earlier implementation using a default value.
- Example: Related
2.8. Partial Maps
- Defined partial maps using an inductive type
partial_map
. - Key functions:
update
: Add or override key-value pairs.find
: Retrieve a value for a key.
- Proof Techniques:
- Case analysis and rewrite.
- Example: Proved
update_eq
(finding an updated key retrieves the value) usingeqb_id_refl
.
2.9. Techniques Summary
- Simplification:
- Simplify goals using
simpl
and reflexivity.
- Simplify goals using
- Case Analysis:
- Analyze inductive data types using
destruct
.
- Analyze inductive data types using
- Induction:
- Apply structural induction for proofs involving recursive data structures.
- Helper Lemmas:
- Prove auxiliary results to support complex proofs.
- Search:
- Use
Search
to find existing results for reuse in proofs.
- Use
3. Exercises
This section lists all the exercises from the Coq file, their respective points, and how they were solved.
3.1. snd_fst_is_swap
- Solution:
Used
destruct
to decompose the pair and appliedreflexivity
.
3.2. fst_swap_is_snd
- Solution:
Used
destruct
to decompose the pair and appliedreflexivity
.
3.3. list_funs
nonzeros
: Defined usingmatch
with anif
statement to filter out zeros.oddmembers
: Used a helper functionodd
to filter odd numbers recursively.countoddmembers
: Usedlength
on the result ofoddmembers
to count odd elements.
3.4. alternate
- Solution:
Used simultaneous pattern matching on two lists (
l1
,l2
) to interleave elements recursively.
3.5. bag_functions
- Solution:
count
: Used recursion andif
to count occurrences.sum
: Defined asapp
(list append).add
: Pre-pended the element to the bag.member
: Checked membership using recursion andif
.
3.6. remove_one
- Solution:
Recursively removed the first occurrence of the given element using an
if
condition.
3.7. remove_all
- Solution:
Removed all occurrences of the given element using recursion and
if
.
3.8. included
- Solution:
Used
count
andremove_one
recursively to check if all elements of one bag are in another.
3.9. add_inc_count
- Solution:
Proved using simplification and a helper lemma for equality (
n =? n = true
).
3.10. eqblist
eqblist
: Defined a recursive equality check for two lists.eqblist_refl
: Proved by induction and simplification usingeq_eq
.
3.11. count_member_nonzero
- Solution:
Simplified the expression to prove that adding
1
ensures its count is non-zero.
3.12. count_member_n_nonzero
- Solution:
Generalized
count_member_nonzero
for any number using simplification and destruct.
3.13. remove_does_not_increase_count
- Solution:
Used induction over the bag and helper lemmas for comparison (
leb
).
3.14. bag_count_sum
- Solution:
Proved that the count of an element in the
sum
of two bags equals the sum of individual counts.
3.15. involution_injective
- Solution:
Proved that every involution is injective by assuming
f(f(x)) = x
and using symmetry in reasoning.
3.16. rev_injective
- Solution:
Proved injectivity of
rev
by reasoning aboutrev(rev(x)) = x
.
3.17. hd_error
- Solution:
Returned
None
for an empty list andSome
for the head of a non-empty list usingmatch
.
3.18. option_elim_hd
- Solution:
Related
hd_error
to the earlierhd
usingdestruct
and simplification.
3.19. eqb_id_refl
- Solution:
Proved reflexivity of
eqb_id
using destruct andeqb_refl
.
3.20. =updateeq
- Solution:
Proved using simplification and the reflexivity of
eqb_id
.
3.21. updateneq
- Solution:
Used simplification and the hypothesis
eqb_id x y = false
.
4. Scores
Name | Points | Notes | Completed? |
---|---|---|---|
snd_fst_is_swap |
1 | Standard | Yes |
fst_swap_is_snd |
1 | Optional | Yes |
list_funs |
2 | Standard | Yes |
alternate |
3 | Advanced | Yes |
bag_functions |
3 | Standard | Yes |
remove_one |
3 | Optional | Yes |
remove_all |
3 | Optional | Yes |
included |
3 | Optional | Yes |
add_inc_count |
2 | Especially useful | Yes |
eqblist |
2 | Standard | Yes |
count_member_nonzero |
1 | Standard | Yes |
count_member_n_nonzero |
1 | Standard | Yes |
remove_does_not_increase_count |
3 | Advanced | Yes |
bag_count_sum |
3 | Standard | Yes |
involution_injective |
3 | Advanced | Yes |
rev_injective |
2 | Advanced | Yes |
hd_error |
2 | Standard | Yes |
option_elim_hd |
1 | Optional | Yes |
eqb_id_refl |
1 | Standard | Yes |
update_eq |
1 | Standard | Yes |
update_neq |
1 | Standard | Yes |
Total Points: 47/47
5. Questions
5.1. TODO Non-decreasing inductive data types
What if we have infinite lists - how will Coq know whether functions over such data types terminates?
Inductive nat_stream : Type := | Cons (n : nat) (s : nat_stream). Fixpoint until_n (n : nat) (s : nat_stream) : natlist := match n with | 0 => [] | S n' => match s with | Cons x s' => x :: until n' s' end end. Fixpoint unravel (s : nat_stream) : natlist := match s with | Cons x s' => x :: unravel s' end.
Here, apparently, both until
and unravel
terminate (or Coq doesn’t complain). Why? I thought unravel
would run infinitely since natstream is “infinite”?
q
6. Metacognition
This was a straightforward chapter. The concepts were familiar and I don’t have any particular questions directly related to the material.
The exercises were straightforward too.
There really wasn’t any thing notable (that isn’t already familiar to me with SML). Hence, this time, I used ChatGPT to take notes.
The most important takeaway is that destruct
works on terms, and that generalizing identities might be easier to prove / make other results easier to prove.
7. Further Knowledge
N/A