Goal True.
begin defer assuming a b c.
assert (a <= b + 1). defer.
assert (b = c + 2). defer.
exact I.
(* [end defer] gives back the subgoals that have been deferred. *)
end defer.
exists 0, 2, 0. omega.
Qed.
Goal True.
begin defer.
assert (H1: 1 + 1 = 2) by defer.
assert (H2: 1 + 2 = 3) by defer.
(* [defer H: foo in g] is a shorthand for [assert (H: foo) by (defer in g)] *)
defer H3: (1 + 3 = 4).
tauto.
end defer.
repeat split; reflexivity.
Qed.
Goal True.
(* It's also possible to explicitly name and refer to the "procrastination group". *)
begin defer assuming a b c in g.
(* [defer] chooses by default the last group of the context. *)
assert (a = b) by defer.
assert (b = c) by (defer in g).
exact I.
end defer.
exists 0, 0, 0. omega.
Qed.
Goal exists (x: nat), x >= 2 /\ x <= 5 /\ x >= 1.
begin defer assuming x.
- exists x. (* We can use the [x] we got as a witness *)
repeat split.
+ defer.
+ defer.
+ (* This case is interesting: we can prove this subgoal from the
first side-condition we procrastinated earlier.
There are several ways of doing that.
*)
(* omega alone is not able to fetch the fact from the group *)
Fail omega.
apply dup.
(* [deferred exploit] iterates on already deferred subgoals *)
{ deferred exploit (fun H => generalize H). omega. }
apply dup.
(* [deferred] adds the procrastinated facts to the goal *)
{ deferred. omega. }
apply dup.
(* [deferred H: E] adds E as H if it has already been deferred. *)
deferred H: (x >= 2). omega.
(* [deferred H: E] can also be used to add facts _derivable_ from deferred facts *)
deferred H: (x >= 1).
{ (* we get a subgoal with all the deferred facts *)
omega. }
assumption.
- end defer.
(* The [eomega] tactic (from Eomega.v) finds instantiations by using a bruteforce strategy. *)
eomega.
Qed.
(* More realistic example, inspired by the proof of asymptotic complexity for the binary search program below.  See the manual for a more detailed description. *)
(* let rec bsearch (arr: int array) v i j = if j <= i then -1 else begin let m = i + (j - i) / 2 in if v = arr.(m) then m else if v < arr.(m) then bsearch arr v i m else bsearch arr v (m+1) j end *)
Admitted.
Definition monotonic (f : nat -> nat) :=
forall x y, x <= y -> f x <= f y.

Lemma solve_cost_ineqs_clean :
exists (f: nat -> nat),
1 <= f 0 /\
monotonic f /\
forall n, 0 < n -> 2 + f (n / 2) <= f n.