0

I’m trying to prove that for a list of bytes a, all bytes are x01 from index 2 to (n-m-2), where n is the length of a:

(forall (i : nat), ((i >= 2) /\ (i < ((n - m) - 1))) -> ((nth_error a i) = (Some x01)))

and I do have this in the context:

H : nth_error a ?j =
      nth_error ([x00; x00] ++ repeat x01 (n - m - 2) ++ repeat x00 m)%list  ?j

So, after intros i i_range. I have:

i : nat
i_range : is_true (1 < i) /\ is_true (i < n - m - 1)
H : nth_error a ?j =
      nth_error ([x00; x00] ++ repeat x01 (n - m - 2) ++ repeat x00 m)%list  ?j
______________________________________(1/1)
nth_error a i = Some x01

Is this a right approach to destruct the RHS of H to eliminate the first two bytes and the last m bytes? If so, how can I do that with respect to i_range? Let me know if my proof strategy is flawed.

Thanks in advance for any suggestion.

Edit:

The last goal's typo is fixed. It was nth_error buff i = Some x01 first and I changed to nth_error a i = Some x01.

  • 1
    Is the `buff` variable in the conclusion related to any of the other terms? If not, the goal cannot be proved, since there are no constraints on `buff` (e.g. it could be empty). – Arthur Azevedo De Amorim Oct 03 '20 at 15:31
  • Sorry, I renamed things for the simplicity. `Buff` is actually `a`. I'll correct the question. Thanks! – Dan Johnson Oct 03 '20 at 15:38
  • Having an existential variable ?j in the context seems a potential problem. In particular, you’ll need ?j to be i, which seems ill-scoped, so you might have the wrong goal. – Blaisorblade Oct 03 '20 at 17:59
  • To @Blaisorblade: This existential variable, `?j`, comes from applying another theorem I have already proven, which is `Theorem list_eq_correctness: forall (l1 l2: list byte), list_eq l1 l2 = true -> (forall (j : nat), nth_error l1 j = nth_error l2 j).` If I need `?j` to be `i`, I can do that by `instantiate ( 1 := i ) in H.` – Dan Johnson Oct 03 '20 at 18:06
  • 1
    Based on the question, that instantiate should fail, because the evar was introduced before i was in scope; if it works, so much the better. (If needed, the fix would be to apply the lemma later.) There’s nothing wrong with the lemma, but it’s unfortunate that you’re not getting the forall statement. – Blaisorblade Oct 03 '20 at 18:08
  • Yeah, but I can instantiate that after `intros i i_range.` So, that's not gonna be a problem. Now, I'm gonna read your answer below. Thanks! – Dan Johnson Oct 03 '20 at 18:13

1 Answers1

1

If you can ensure H starts with “forall j,”, the goal should be provable. I am not sure I understand the strategy you suggests, but I’d rewrite ntherror (prefix ++ foo ++ bar) i to ntherror foo (i - 2) (using suitable lemmas, either existing or provable), then since foo is defined using repeat, rewrite ntherror (repeat baz x01) to x01. All these lemmas have arithmetic side conditions that should hold.

Yves
  • 3,808
  • 12
  • 12
Blaisorblade
  • 6,438
  • 1
  • 43
  • 76
  • (Sorry for typos, hope it’s clear anyway; I’m on mobile). – Blaisorblade Oct 03 '20 at 18:07
  • No worries! That was really a great help. I did as you said by using two existing lemmas, as in `rewrite nth_error_app2 in H. simpl in H. rewrite nth_error_app1 in H.` to get rid of *prefix* and *bar*. Then, I removed *foo* by adding `assert (nth_error_repeat_elim: forall (i j : nat) (b : byte), j < i -> nth_error (repeat b i) j = Some b). admit. rewrite nth_error_repeat_elim in H.` and proved my goal by `apply H.` Finally, I used `i_range` to prove the arithmetic side conditions that those rewrites added as next sub goals. Thanks a lot, @Blaisorblade! – Dan Johnson Oct 04 '20 at 03:43