October 13, 2025
Learning Objectives for Theoretical Machines
import utils; from utils import rf
from lastDigitIsEven import lastDigitIsEven
def isOddViaReduction(inString):
inStringPlusOne = int(inString) + 1
return lastDigitIsEven(str(inStringPlusOne))
def testisOddViaReduction():
testVals = [('-2', 'no'),
('0', 'no'),
('2', 'no'),
('3742788', 'no'),
('-1', 'yes'),
('1', 'yes'),
('3', 'yes'),
('17', 'yes'),
('3953969', 'yes'),
]
for (inString, solution) in testVals:
val = isOddViaReduction(inString)
utils.tprint(inString, ':', val)
assert val == solution
isOddViaReduction
uses lastDigitIsEven
to solve the isOdd
problemisOddViaReduction
solves IsOdd
by reduction it to LastDigitIsEven
YesOnString
:
ContainsGAGA
is uncomputableHaltsOnString
is uncomputableYesOnString
\(\rightarrow\) ContainsGAGA
ContainsGAGA
is uncomputableYesOnString
is uncomputableYesOnString
\(\leq_T\) ContainsGAGA
YesOnString
: Given program \(P\) and input \(I\), does \(P(I)=\) “yes”?ContainsGAGA
: Given program \(P\) and input \(I\), does \(P(I)\) contain the string “GAGA”?YesOnString
into an instance of ContainsGAGA
(i.e., ContainsGAGA
will “call” YesOnString
)ContainsGAGA
to solve YesOnString
import utils; from utils import rf
from GAGAOnString import GAGAOnString # oracle function
def yesViaGAGA(progString, inString):
singleString = utils.ESS(progString, inString)
return GAGAOnString(rf('alterYesToGAGA.py'), singleString)
def testYesViaGAGA():
testvals = [
('containsGAGA.py', 'TTTTGAGATT', 'yes'),
('containsGAGA.py', 'TTTTGAGTT', 'no'),
('isEmpty.py', '', 'yes'),
('isEmpty.py', 'x', 'no'),
]
for (filename, inString, solution) in testvals:
val = yesViaGAGA(rf(filename), inString)
utils.tprint(filename + ":", val)
assert val == solution
YesOnString
problem using an “oracle” for ContainsGAGA
, meaning we can solve known problem with new oneContainsGAGA
is uncomputable?ContainsGAGA
is computableYesOnString
is computable (via our reduction)YesOnString
is uncomputable, which we have previously proven in a separate proof by contradiction!ContainsGAGA
must be uncomputableContainsGAGA
is uncomputable!YesOnString
, previously proven uncomputable
YesOnEmpty
(does \(P(\epsilon)=\) “yes”?)YesOnAll
(does \(P(I)=\) “yes” for all \(I\)?)YesOnSome
(does \(P(I)=\) “yes” for some \(I\)?)ContainsGAGA
(does \(P(I)\) output contain “GAGA”?)HaltsOnString
, HaltsOnEmpty
, HaltsOnAll
NumCharsOnString
, NumStepsOnString
Importantly, all of these uncomputability proofs start from a single problem, such as YesOnString
, that we’ve proven to be uncomputable!
Building hierarchies: Transitivity helps organize problems by hardness
Viewing hierarchies: See the relationships between problems in a tree
Tree Interpretation: Node at the top is the “starting point” of the Turing reduction chain! Okay, let’s see what this looks like!
YesOnString
is at least as hard as HaltsOnString
HaltsOnString
is at least as hard as HaltsOnEmpty
HaltsOnString
is at least as hard as NumStepsOnString
YesOnString
is at least as hard as HaltsOnEmpty
YesOnString
is at least as hard as NumStepsOnString
YesOnString
to YesOnEmpty
import utils; from utils import rf
from yesOnEmpty import yesOnEmpty # oracle function
def yesViaEmpty(progString, inString):
utils.writeFile('progString.txt', progString)
utils.writeFile('inString.txt', inString)
return yesOnEmpty(rf('ignoreInput.py'))
YesOnString
\(\leq_T\) YesOnEmpty
YesOnEmpty
is at least as hard as YesOnString
YesOnEmpty
is uncomputablehaltOnString
is uncomputable?alterYesToHalt
programimport utils; from utils import rf
from universal import universal
def alterYesToHalt(inString):
(progString, newInString) = utils.DESS(inString)
val = universal(progString, newInString)
if val == 'yes':
# return value is irrelevant, since returning any string halts
return 'halted'
else:
# deliberately enter infinite loop
utils.loop()
def testAlterYesToHalt():
for (progName, inString, solution) in [
('containsGAGA.py', 'GAGAGAGAG', 'halted'),
('containsGAGA.py', 'TTTTGGCCGGT', None),
]:
combinedString = utils.ESS(rf(progName), inString)
val = utils.runWithTimeout(None, alterYesToHalt, combinedString)
utils.tprint( (progName, inString), ":", val )
assert val == solution
alterYesToHalt
will be used in the next reduction!alterYesToHalt
uses source code provided by the textbookyesViaHalt
programimport utils; from utils import rf
from haltsOnString import haltsOnString # oracle function
def yesViaHalts(progString, inString):
singleStr = utils.ESS(progString, inString)
return haltsOnString(rf('alterYesToHalt.py'), singleStr)
def testYesViaHalts():
testvals = [
('containsGAGA.py', 'TTTTGAGATT', 'yes'),
('containsGAGA.py', 'TTTTGAGTT', 'no'),
('isEmpty.py', '', 'yes'),
('isEmpty.py', 'x', 'no'),
]
for (filename, inString, solution) in testvals:
val = yesViaHalts(rf(filename), inString)
utils.tprint(filename + ":", val)
assert val == solution
haltsOnString
“oracle” to solve YesOnString
, meaning YesOnString
\(\leq_T\) HaltsOnString
. Wow, we have shown that HaltsOnString
is uncomputable!YesOnString
, many problems are uncomputable!Proofgrammers