On 14.02.2014 04:39, Bill Richter wrote:
> I guess I understood that REWRITE_TAC used a complicated algorithm in order
> to avoid infinite looping. So I think I didn't express my question very
> well. I tend to think that it's not good coding on my part to rely on
> features that I don't even understand. I would think that the only sensible
> way to handle my code above was to find a different way of solving the
> problem, such as your solution of using ONCE_REWRITE_TAC to symmetry all
> three dist expressions. Any thoughts? For instance, isn't it possible that
> you would change the REWRITE_TAC algorithm?
> In any case, thanks, as you answered my question: this behavior of
> REWRITE_TAC that I didn't understand is caused by REWRITE_TAC being quite
> ingenious and complicated! That's a perfectly acceptable answer to me right
> now.
Hi Bill,
I would say what is bad coding is not to rely on features you don't
understand but on features that are actually undocumented/unintended.
Here, the ordering chosen is indeed ingenious to prevent some often-met
looping situations.
However, as John pointed out it is also completely arbitrary (in your
case it just applies the rewrite you wanted because Ocaml orders symbols
as follows: x < x' < x'').
So the fact that you obtained what you wanted is completely random and
not actually based on the ingenuity of the tactic.
In particular, if the Ocaml implementors decide randomly to change the
order of strings then the script does not work anymore.
So ONCE_REWRITE_TAC is indeed better here. But I personally still don't
like it so much since it does not really reflect your intention:
your intention is to rewrite the middle "dist", not to rewrite "once".
So a better solution would be to use GEN_REWRITE_TAC as you know, or
PATH_CONV.
However I still don't like these ones so much since they force you to
give precise information about the location of the rewrite.
This is, first, annoying, and second, can break easily if ever you
change later on some definitions (the sequence of xxx_CONV given to
GEN_REWRITE_TAC could slightly change).
So actually, the best version in my opinion is just to give DIST_SYM to
MESON_TAC:
let OPEN_BALL = prove
(`!x e. open(ball(x,e))`,
REWRITE_TAC[open_def; ball; IN_ELIM_THM] THEN
MESON_TAC[DIST_SYM; REAL_SUB_LT; REAL_LT_SUB_LADD; REAL_ADD_SYM;
REAL_LET_TRANS; DIST_TRIANGLE_ALT]);;
Then you don't even have to care about technical details like the number
or the position of rewrites.
Note that - sorry to insist on it again... - the library that I've been
advertising a couple of times, https://github.com/aravantv/impconv,
provides a tactic specially intended to provide a nice solution to this
sort of problem: TARGET_REWRITE_TAC.
It is an attempt and does not claim to solve everything (and, in
particular, is inefficient as soon as you give it too many theorems) but
it gives an idea of a possible direction to go to obtain a solution
that, for me, would be perfect.
"TARGET_REWRITE_TAC ths th" tries all possible rewrites on every
possible path using the theorems in the list ths, and picks the first
rewrite which allows to obtain a goal where we can apply th.
If that's not clear I refer to the manual of the library, which also
contains examples.
The overall idea is to change from the question "Where do I want my
rewrite to apply?" or "How many times do I want my rewrite to apply?" to
"For which purpose do I want my rewrite to apply?".
To the former questions you answer informally by "in the middle dist
term" or by "1 time", whereas for the latter you answer "in order to
rewrite using the theorem th".
It follows better the intention of the human behind the proof and does
not require that you give technical information like the position or the
number of rewrites.
In your example, the purpose of the rewrite is to apply the triangular
inequality, i.e., DIST_TRIANGLE, so one would ideally write
TARGET_REWRITE_TAC [DIST_SYM] DIST_TRIANGLE
(which means informally "try every single rewrite with DIST_SYM - in
first position, in the middle, in the last position - and pick the one
that allows to make use of DIST_TRIANGLE").
In your example this is not enough actually since rewriting with
DIST_SYM does not allow to rewrite immediately with DIST_TRIANGLE: you
also need quite a bunch of intermediate theorems like REAL_SUB_LT,
REAL_LET_TRANS, etc.
So you should give these theorems to TARGET_REWRITE_TAC as follows:
TARGET_REWRITE_TAC [DIST_SYM; REAL_SUB_LT; REAL_LET_TRANS; ...]
DIST_TRIANGLE
Unfortunately this particular case is way too complex that
TARGET_REWRITE_TAC can handle... :-(
But it still demonstrates the motivation behind TARGET_REWRITE_TAC.
Cheers,
V.
--
Dr Vincent Aravantinos
Analysis and Design of Dependable Systems
fortiss GmbH <www.fortiss.org/en>
T +49 (0)89 360 35 22 33 | Fx +49 (0)89 360 35 22 50
Guerickestrasse 25 | 80805 Munich | Germany
------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience. Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk
_______________________________________________
hol-info mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/hol-info