Switch day 1 Coq post to use submodule'd code.
This commit is contained in:
parent
06014eade9
commit
6f9a2ce092
|
@ -26,7 +26,7 @@ let's write a helper function that, given a number `x`, tries to find another nu
|
||||||
`y` such that `x + y = 2020`. In fact, rather than hardcoding the desired
|
`y` such that `x + y = 2020`. In fact, rather than hardcoding the desired
|
||||||
sum to `2020`, let's just use another argument called `total`. The code is quite simple:
|
sum to `2020`, let's just use another argument called `total`. The code is quite simple:
|
||||||
|
|
||||||
{{< codelines "Coq" "aoc-coq/day1.v" 7 14 >}}
|
{{< codelines "Coq" "aoc-2020/day1.v" 11 18 >}}
|
||||||
|
|
||||||
Here, `is` is the list of numbers that we want to search.
|
Here, `is` is the list of numbers that we want to search.
|
||||||
We proceed by case analysis: if the list is empty, we can't
|
We proceed by case analysis: if the list is empty, we can't
|
||||||
|
@ -43,7 +43,7 @@ for our purposes when the argument being case analyzed is given first.
|
||||||
We can now use `find_matching` to define our `find_sum` function, which solves part 1.
|
We can now use `find_matching` to define our `find_sum` function, which solves part 1.
|
||||||
Here's the code:
|
Here's the code:
|
||||||
|
|
||||||
{{< codelines "Coq" "aoc-coq/day1.v" 16 24 >}}
|
{{< codelines "Coq" "aoc-2020/day1.v" 20 28 >}}
|
||||||
|
|
||||||
For every `x` that we encounter in our input list `is`, we want to check if there's
|
For every `x` that we encounter in our input list `is`, we want to check if there's
|
||||||
a matching number in the rest of the list. We only search the remainder of the list
|
a matching number in the rest of the list. We only search the remainder of the list
|
||||||
|
@ -72,13 +72,13 @@ formally as follows:
|
||||||
|
|
||||||
And this is how we write it in Coq:
|
And this is how we write it in Coq:
|
||||||
|
|
||||||
{{< codelines "Coq" "aoc-coq/day1.v" 26 27 >}}
|
{{< codelines "Coq" "aoc-2020/day1.v" 30 31 >}}
|
||||||
|
|
||||||
The arrow, `->`, reads "implies". Other than that, I think this
|
The arrow, `->`, reads "implies". Other than that, I think this
|
||||||
property reads pretty well. The proof, unfortunately, is a little bit more involved.
|
property reads pretty well. The proof, unfortunately, is a little bit more involved.
|
||||||
Here are the first few lines:
|
Here are the first few lines:
|
||||||
|
|
||||||
{{< codelines "Coq" "aoc-coq/day1.v" 28 31 >}}
|
{{< codelines "Coq" "aoc-2020/day1.v" 32 35 >}}
|
||||||
|
|
||||||
We start with the `intros is` tactic, which is akin to saying
|
We start with the `intros is` tactic, which is akin to saying
|
||||||
"consider a particular list of integers `is`". We do this without losing
|
"consider a particular list of integers `is`". We do this without losing
|
||||||
|
@ -157,7 +157,7 @@ is zero. This means we're done with the base case!
|
||||||
The inductive case is the meat of this proof. Here's the corresponding part
|
The inductive case is the meat of this proof. Here's the corresponding part
|
||||||
of the Coq source file:
|
of the Coq source file:
|
||||||
|
|
||||||
{{< codelines "Coq" "aoc-coq/day1.v" 32 36 >}}
|
{{< codelines "Coq" "aoc-2020/day1.v" 36 40 >}}
|
||||||
|
|
||||||
This time, the proof state is more complicated:
|
This time, the proof state is more complicated:
|
||||||
|
|
||||||
|
@ -284,14 +284,14 @@ Coq proofs is to actually step through them in the IDE!
|
||||||
|
|
||||||
First on the list is `find_matching_skip`. Here's the type:
|
First on the list is `find_matching_skip`. Here's the type:
|
||||||
|
|
||||||
{{< codelines "Coq" "aoc-coq/day1.v" 38 39 >}}
|
{{< codelines "Coq" "aoc-2020/day1.v" 42 43 >}}
|
||||||
|
|
||||||
It reads: if we correctly find a number in a small list `is`, we can find that same number
|
It reads: if we correctly find a number in a small list `is`, we can find that same number
|
||||||
even if another number is prepended to `is`. That makes sense: _adding_ a number to
|
even if another number is prepended to `is`. That makes sense: _adding_ a number to
|
||||||
a list doesn't remove whatever we found in it! I used this lemma to prove another,
|
a list doesn't remove whatever we found in it! I used this lemma to prove another,
|
||||||
`find_matching_works`:
|
`find_matching_works`:
|
||||||
|
|
||||||
{{< codelines "Coq" "aoc-coq/day1.v" 49 50 >}}
|
{{< codelines "Coq" "aoc-2020/day1.v" 53 54 >}}
|
||||||
|
|
||||||
This reads, if there _is_ an element `y` in `is` that adds up to `k` with `x`, then
|
This reads, if there _is_ an element `y` in `is` that adds up to `k` with `x`, then
|
||||||
`find_matching` will find it. This is an important property. After all, if it didn't
|
`find_matching` will find it. This is an important property. After all, if it didn't
|
||||||
|
@ -310,7 +310,7 @@ that all lists from this Advent of Code puzzle are guaranteed to have two number
|
||||||
add up to our goal, and that these numbers are not equal to each other. In Coq,
|
add up to our goal, and that these numbers are not equal to each other. In Coq,
|
||||||
we state this as follows:
|
we state this as follows:
|
||||||
|
|
||||||
{{< codelines "Coq" "aoc-coq/day1.v" 4 5 >}}
|
{{< codelines "Coq" "aoc-2020/day1.v" 8 9 >}}
|
||||||
|
|
||||||
This defines a new property, `has_pair t is` (read "`is` has a pair of numbers that add to `t`"),
|
This defines a new property, `has_pair t is` (read "`is` has a pair of numbers that add to `t`"),
|
||||||
which means:
|
which means:
|
||||||
|
@ -323,7 +323,7 @@ which means:
|
||||||
When making claims about the correctness of our algorithm, we will assume that this
|
When making claims about the correctness of our algorithm, we will assume that this
|
||||||
property holds. Finally, here's the theorem we want to prove:
|
property holds. Finally, here's the theorem we want to prove:
|
||||||
|
|
||||||
{{< codelines "Coq" "aoc-coq/day1.v" 64 66 >}}
|
{{< codelines "Coq" "aoc-2020/day1.v" 68 70 >}}
|
||||||
|
|
||||||
It reads, "for any total `k` and list `is`, if `is` has a pair of numbers that add to `k`,
|
It reads, "for any total `k` and list `is`, if `is` has a pair of numbers that add to `k`,
|
||||||
then `find_sum` will return a pair of numbers `x` and `y` that add to `k`".
|
then `find_sum` will return a pair of numbers `x` and `y` that add to `k`".
|
||||||
|
@ -335,7 +335,7 @@ we want to confirm that `find_sum` will find one of them. Finally, here is the p
|
||||||
I will not be able to go through it in detail in this post, but I did comment it to
|
I will not be able to go through it in detail in this post, but I did comment it to
|
||||||
make it easier to read:
|
make it easier to read:
|
||||||
|
|
||||||
{{< codelines "Coq" "aoc-coq/day1.v" 67 102 >}}
|
{{< codelines "Coq" "aoc-2020/day1.v" 71 106 >}}
|
||||||
|
|
||||||
Coq seems happy with it, and so am I! The bug I mentioned earlier popped up on line 96.
|
Coq seems happy with it, and so am I! The bug I mentioned earlier popped up on line 96.
|
||||||
I had accidentally made `find_sum` return `None` if it couldn't find a complement
|
I had accidentally made `find_sum` return `None` if it couldn't find a complement
|
||||||
|
|
Loading…
Reference in New Issue
Block a user