Is there a way to check if a pattern is infinite, say before you do
Pseq([1, 2, 3]).asStream.all
or is there perhaps a quark that makes it possible?
Is there a way to check if a pattern is infinite, say before you do
Pseq([1, 2, 3]).asStream.all
or is there perhaps a quark that makes it possible?
I believe you’ve just asked if SC solves the halting problem, which is undecidable: “In computability theory, the halting problem is the problem of determining, from a description of an arbitrary computer program and an input, whether the program will finish running, or continue to run forever. Alan Turing proved in 1936 that a general algorithm to solve the halting problem for all possible program–input pairs cannot exist.”
We’re not gonna do better than Turing here
But I did, some years ago, try to “estimateLength” of patterns. It’s not reliable – sort of an abandoned fragment – but it should search through patterns and tend toward inf
if some subpattern has an infinite length.
Pseq([1, 2, Pn(3, inf)], 1).estimateLength // inf
Pser([1, 2, Pn(3, inf)], 2).estimateLength // inf but that's wrong
// Pswitch: 'which' pattern means the inf subpattern
// will never be embedded... but estimateLength doesn't
// know that, so it just returns inf
Pswitch([1, 2, Pn(3, inf)], Pwhite(0, 1, 6)).estimateLength
Use at your own risk. It should be OK for relatively simple Pseq, Prand, Pxrand etc. patterns. Complex patterns, don’t trust it.
ddwPatterns quark.
hjh
Many thanks for the insight and suggestion, I’ll look into the quark!
In the unreliable cases, will your method return inf
even if it is finite, or the other way around, or still undecided?
For my use case it’s sufficient to know whether it is guaranteed to be finite or not, so a method like .isKnownToBeFinite
could be useful.
I was thinking of adding methods like below, but I guess the method added to Object
is questionable, since a new .embedInStream
method could also be added to any class.
Just thinking out loud
+ Object {
isKnownToBeFinite {
^true;
}
}
+ Stream {
isKnownToBeFinite {
^false;
}
}
+ Pattern {
isKnownToBeFinite {
^false;
}
}
+ Pseq {
isKnownToBeFinite {
^((this.repeats != inf) && (this.list.collect({arg item; item.isKnownToBeFinite}).includes(false).not));
}
}
Turing proved that there is no reliable algorithm that can determine this.
It may be possible to handle a subset of cases. If that subset includes most typical cases, then it may be useful – but it can’t be both complete and accurate.
I posted a couple of examples where it returns inf even when the pattern isn’t, so the first question is definitely yes. “Other way around,” probably not but this code is not tested rigorously enough to be sure.
hjh