I was working is this simple exercise about writing certified function using subset types. The idea is to first write a predecessor function
pred : forall (n : {n : nat | n > 0}), {m : nat | S m = n.1}.
and then using this definition give a funtion
pred2 : forall (n : {n : nat | n > 1}), {m : nat | S (S m) = n.1}.
I have no problem with the first one. Here is my code
Program Definition pred (n : {n : nat | n > 0}) : {m : nat | S m = n.1} :=
match n with
| O => _
| S n' => n'
end.
Next Obligation. elimtype False. compute in H. inversion H. Qed.
But I cannot workout the second definition. I trying to write these definition
Program Definition pred2 (n : {n : nat | n > 1}) : {m : nat | S (S m) = n.1}
:= pred (pred n).
I managed to prove the two first obligations
Next Obligation. apply (gt_trans n 1 0). assumption. auto. Qed.
Next Obligation.
destruct pred.
simpl.
simpl in e.
rewrite <- e in H.
apply gt_S_n in H; assumption.
Qed.
But for the last obligation I get stuck because when I try to do a case analysis for the return type of pred the new hypotesis are not rewrited in the goal.
I tried the following tactics with no results.
destruct (pred (n: pred2_obligation_1 (n ; H))).
destruct (pred (n; pred2_obligation_1 (n ; H))) eqn:?.
rewrite Heqs.
I know that I can with write pred2 directly, but the idea is to use and compose the function pred.
The reason
destruct
doesn't have any effect is probably because what you're trying to do case analysis on doesn't occur in the goal. The implicit arguments of that term probably don't match the implicit arguments of the term in the goal. Either way, you can't do case analysis on that term without making the goal ill-typed.But you can prove that obligation by case analysis on
n
.I was also able to prove some helper theorems, but I wasn't able to use them because of all the type dependency.
I had never seen
destruct
used on a function. I'm surprised Coq doesn't complain that that function isn't inductively defined.