On 25/11/2025 20:38, Kaz Kylheku wrote:
On 2025-11-25, Mike Terry
<news.dead.person.stones@darjeeling.plus.com> wrote:
On 24/11/2025 22:45, Kaz Kylheku wrote:
On 2025-11-24, Mike Terry
<news.dead.person.stones@darjeeling.plus.com> wrote:
For HHH/HHH1 the issue is different - they are clearly different
algorithms since they give
different results, but it's not pointer comparison that is the
problem - it's the use of mutable
global data: HHH and HHH1 each use /their own/ global variable
[viz their global trace tables]
within their algorithms.
Yes; this is an issue that I'm glossing over. HHH and HHH1 are not pure >>>> functions since they react to this mutating state.
Multiplie instances of HHH share an execution trace buffer, allocated
by the first call to HHH.
Multiple instances of HHH1 also share an execution trace buffer
distinct
from that one allocated by the first call to HHH1.
Simulations conducted by any level of HHH only feed HHH's buffer,
and simulations conducted by any level of HHH1 only feed HHH1's
buffer.a
Exactly. That explains why HHH and HHH1 are not proper clones of
each other [whatever PO claims],
and hence why they produce different results.
That is all gapingly incorrect; yet if these aspects were fixed, there >>>> would still be a problem if we evaluate HHH1 != HHH as dincating that
they are different function.
The traces I showed yesterday demonstrate that fixing the HHH1 != HHH
issue is not relevant to the
HHH(DD) != HHH1(DD) problem. When you fix the impurity issues, we
have HHH(DD) == HHH1(DD), because
then HHH1 is a proper clone of HHH. (I didn't show those traces, but
I'm confident they would work
as described.)
I now agree with that. HHH1 only ever appears as a top-level call for
probing HHH1(DD). Top-level calls are executng in side the x86emu, but
not in a single stepping mode whereby their instruction traces are
inserted into any buffer. Only specfic code in Halt7 does that.
Insertion into the buffer begins with the simulation of DD, whch does
not have HHH1 in its call graph.
So, where have we got to?
I think we both agree that fixing impurity fixes the "incorrect
cloning" (aka HHH1 and HHH giving
divergent results) issue. [At least in respect of the specific case
of HHH/HHH1, if not for cloning
in general.]
I think we both agree that fixing the HHH != HHH1 (address
comparison) issue is irrelevant to fixing
the incorrect cloning issue, at least as experienced specifically in
PO's cloning of HHH-->HHH1.
Yes, it is not relevant to that test case, but nevertheless is it not
correct to assume that different function pointers are a different
functions.
Well, TMs can contain "equivalent" sub-algorithms with different state labels - effectively "the same" functions at different addresses.
There's nothing unusual in that. And C compilers can generate
equivalent functions at different addresses, no problem. The
optimisation phase may or may not recognise this and fold them into a
single function. As you say, this can't always be done in general, but
its straight-forward in some cases where the code is essentially identical.
If you are analysing that program, you would see that the functions were distinct (i.e. they are at different addresses). I suppose by default,
you should make no assumptions regarding whether or not they are
equivalent without further analysis. Quite possibly it doesn't matter
for your purposes whether the functions are equivalent.
In PO's case, he only needs to recognise that a specific (as defined by address) function (HHH) is being emulated recursively. If there are
other copies of HHH around at different addresses, his rule just doesn't care. If PO's argument assumed that HHH and HHH1 /must/ produce
different results because they were at different addresses, we'd quickly point out that that assumption is false. But he does not argue that.
What does he argue? Re HHH/HHH1 he argues that /if/ emulated behaviour
of DD was independent of the emulator, /then/ HHH/HHH1 would be
equivalent (since their code is "the same" and the emulation would also
be the same) and so their result would be the same. But their result
is /not/ the same, so emulated DD behaviour must depend on who is doing
the emulating. [Hey, I've actually made it sound as though PO is
capable of making a coherent argument! Iron-man argument, and all that...]
Of course that is nonsense, because HHH/HHH1 code is not "the same" in
the required sense, due to misuse of global variables etc..
Putting HHH1 aside, for his HHH "infinite recursion detected" pattern he assumes that /the same/ addresses in different levels of emulation correspond to the same function. That's quite different from what we're discussing.
There's probably a discussion to be had around that, but I see it as
akin to identifying (say) state 7 in TM-desc <I> being simulated at
level [1] with being state 7 in /the same/ TM-desc <I> being simulated
at level [2]. In principle a TM could do that, right? It would need to know that the TM-desc is the same, but they are just text strings, so
that is plausible. In PO-world there is just one address space so its
kind of built in that the assumption works. Hmm.
Any halting decisions predicated on such a comparison are
suspicious. Doign the comparison properly is as hard as deciding
halting; therefore no halting decider may rely on the answer to "are
these two functions equivalent". That amounts to begging the question.
What's left is whether the address comparison issue "is still a
problem". I don't see it as
relevant to anything much, but you see it as important in some way.
I've explained why I don't
consider it relevant, but that doesn't convince you, so I'll leave it
at that.
Even if function address comparison is used, it will catch some cases of
recursive loops where functions are incorrectly concluded to be
different like:
f() { g(); }
g() { h(); }
h() { k(); }
k() { g(); } // k is same as f
I'm not clear on what this is meant to show. I see k and f are "equivalent" in their functionality. PO's (unsound) rule would
presumably see f-->g-->h-->k-->g, and g has been called recursively -
but it would NOT match at this point because although the target g has
been called twice, the calls are from different addresses viz somewhere inside f vs somewhere inside k.
That's not a problem. PO does not claim his decider catches all
recursive simulations.
Continuing, g-->h, and now PO's rule will match, because h has been
called twice from the same address somewhere in g. So HHH correctly decides non-halting.
All fine, unless you're saying the rule /should/ have matched earlier
when g was called. That would simply be a different rule. The decider here isn't "incorrectly concluding that k and f are different" - it's
simply agnostic on that point.
That's an argument that a decider /isn't/ required to identify that k is
the same as f.
BTW, don't you think that this scenario is exactly why PO is so
convinced his "infinite recursion" pattern is sound, simply being unable
to understand the differences between this example (Call) and his HHH/DD example (Simulation)?
Mike.
| Sysop: | DaiTengu |
|---|---|
| Location: | Appleton, WI |
| Users: | 1,089 |
| Nodes: | 10 (0 / 10) |
| Uptime: | 153:45:27 |
| Calls: | 13,921 |
| Calls today: | 2 |
| Files: | 187,021 |
| D/L today: |
3,744 files (941M bytes) |
| Messages: | 2,457,162 |