The addition of bounds and bounds-triggered constraints to
magichex.4th did require thinking through a lot of cases, e.g.:
* Has the bound changed? E.g, if A in [3,7], and we get A<10, the
bounds don't change. Only if the bounds change, bounds-triggered
constraints should be woken up, or we get an infinite loop.
* Is a bound outside the range [0,63]? This may needs special
handling, because for the potential values we allow only values
inside [0,63].
* Is the target bound an earlier-excluded interior value? E.g., if A
has the starting bounds [3,7] and the possible values {3,4,6,7}, and
we now get A<6, we want to set the new bounds not to [3,5], but to
[3,4].
* Does the target bound mean that the variable is instantiated? E.g.,
if we start with A in [3,7], and we get A<4, the result is A=3. But
also, if we have A in [3,7] with possible values {3,5,6,7}, and A<5,
the result is that A=3. If the variable is instantiated, the
value-constraints have to be triggered.
* Does the target bound mean that the variable can have no value?
E.g., if we start with A in [3,7], and we get A<1, A can have no
value, and we have to backtrack.
It's unsurprising that, with so many considerations in addition to the
usual difficulties of Forth programming, I introduced some bugs.
I had the fear that the bugs would be hard to find, and initially most
of them looked mysterious, and potentially very hard to find. It did
not help that the backtraces did not work as intended, because the
program uses exceptions for backtracking; Gforth has NOTHROW for this situation, but it did not work as intended (I have to investigate that
yet).
Still, the bugs were not that hard to find in the end; looking at the
times in the commits when I hunted for bugs back-to-back, I see that
they cost me between 12 and 47 minutes. In addition to inserting
tracers (~~), I changed the labeler to only label one or two variables
and show the effects afterwards, or wrote a helper word that
instantiated these variables; the latter approach eliminated the
CATCHes of the labeling and thus restored the backtracing
functionality, which was quite valuable.
You find the project on <
https://github.com/AntonErtl/magic-hexagon>
Here are the commits that fixed the bugs, and a description of the
bug.
commit 8af8cc0b99fb28d52a404a58118f03f5897b9496
Stack error (a DUP too much).
commit d8a9aabb414ba28a68aafd458103b9b2039adbc9
ARRAYSUM was value-triggered (buggy), fixed to bounds-triggered
(I forgot to change it from magichex.4th)
commit 7146668e5564d3638ba8b68e4eee070065a52e81
I had commented out some code while debugging 8af8cc0b99fb28d52a404a58118f03f5897b9496 and this bugfix undid that.
The stack depth after CATCH was wrong; first attempt to fix that.
commit 677c6c90a8b926659b8a21428c67843f75a88860
Proper fix for the stack depth after CATCH. I wonder why that stack
depth handling works (or at least seems to) in magichex.4th (the code
is directly from there).
commit 42d6a0aa3abcc4447f203a1d2010813eca3b5043
Deal with the case where the target bound is outside [0,63].
commit 07e4d73d66a5735f2cf8fb53ae809a636a7b9bcb
stack handling
commit 1868476348908c89422818b77f8d4bea00bfe7a4
I had updated the wrong bounds for the #< constraint.
- anton
--
M. Anton Ertl
http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs:
http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard:
https://forth-standard.org/
EuroForth 2022:
https://euro.theforth.net
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)