$ python
>>> import z3
>>> x, y = z3.Ints('x y')
>>> s = z3.Solver()
>>> s.add(z3.Not(z3.ForAll([x], z3.Exists([y], z3.And(y >= x, y % x == 0)))))
>>> s.check()
unknown
z3 returns unknown (if it had returned "unsat", it would have been possible to extract a resolution-refutation proof), and there's not much that can be done with the unknown. $ coqtop
Require Import NArith.
Require Import Omega.
Lemma x_le_fact : forall x, x <= fact x.
induction x;.
- simpl; omega.
- simpl; admit. (* Proving `x <= fact x -> S x <= fact x + x * fact x` left unsolved here *)
Admitted.
Goal forall (x : nat), exists (y : nat), y >= x /\ Nat.modulo y x = 0.
intros x; exists (fact x).
split.
- unfold ">=". apply x_le_fact.
- induction x.
+ simpl; reflexivity.
+
(* goal here is `fact (S x) mod S x = 0` *)
unfold fact; fold fact.
(* goal here is `(S x * fact x) mod S x = 0` *)
rewrite (Nat.mul_comm (S x) (fact x)).
(* goal here is `(fact x * S x) mod S x = 0` *)
apply (Nat.mod_mul (fact x) (S x)).
discriminate.
Qed.
Unlike z3, you need to manually tell Coq what the steps are, but it gives you feedback on which steps are correct, and what assumptions are available and what subgoals still remain at each step (I've included some of those as comments, running the proof through the interpreter shows more detail). int main() {
char buf[20];
fgets(buf, sizeof buf, stdin);
printf(buf);
return 0;
}
An attacker writing to the program's stdin can read at offsets to the stack (e.g. "%42$x"), read the contents of arbitrary non-null memory (e.g. "ABCD%5$s", where ABCD is a 32-bit memory address, and 5 is the positional parameter corresponding to the start of buf), and write an arbitrary value to an arbitrary address (e.g. "ABCD%38x%5$n", to write the value 42 to address 0x44434241).