Every goal that I have encountered in Isabelle so far that could be solved using arith
could also be solved by presburger
and vice versa, for example
lemma "odd (n::nat) ⟹ Suc (2 * (n div 2)) = n"
by presburger (* or arith *)
What's the difference between the two solvers? Examples of goals that one can solve but the other can't would be nice.
Edit: I managed to come up with a lemma proved by arith
that presburger
can't handle. It seems like this has something to do with real numbers:
lemma "max i (i + 1) > (i::nat)" by arith -- ✔
lemma "max i (i + 1) > (i::nat)" by presburger -- ✔
lemma "max i (i + 1) > (i::real)" by arith -- ✔
lemma "max i (i + 1) > (i::real)" by presburger -- ✘
presburger
cannot handle real arithmetic, whilearith
can. I thinkpresburger
is just an implementation of the well-known decision procedure for Presburger arithmetic whilearith
is a collection of various decision procedures for arithmetic. There is alsolinarith
; I do not know how that fits in. – Maseralinarith
before (is there a comprehensive list of Isabelle/HOL methods somewhere?) – Strawserlemma "(2 * i) div 2 = (i::real)" by presburger
(which works for me) a counter-example to "presburger
cannot handle real arithmetic"? – Strawserreal (2 * i div 2) = real i
, which is easily reduced to2 * i div 2 = i
. The reason why Isabelle inserts these coercions is thatdiv
is not defined for reals, so Isabelle defaults toint
and inserts coercions to make the types work out. – Masera