Rice's theorem states that every non-trivial semantic property of Turing machines is undecidable: there is no algorithm to determine whether a given machine computes a function with property P (where P is neither vacuously true nor false for all functions). This unifies dozens of undecidability results and shows that analyzing program behavior beyond syntax is fundamentally hard.
Identify which properties are semantic (depend on the computed function) versus syntactic (depend on the machine description), then apply Rice's theorem to candidate properties.
Your prerequisite work with Rice's theorem established the core result: every non-trivial semantic property of Turing machines is undecidable. Now the task is learning to *apply* it fluently. The first skill is distinguishing semantic from syntactic properties. A syntactic property depends only on the machine description itself — its states, transitions, tape symbols — not on what the machine computes. "This machine has more than 50 states" is syntactic; you can read it off the description without simulating anything. A semantic property depends on the *function computed* — the input-output behavior of the machine. "This machine halts on every input" is semantic; it makes a claim about infinitely many possible runs.
Rice's theorem applies exactly when two conditions hold: the property is semantic, and it is non-trivial (some machines have it and some don't). To use the theorem, you simply verify these conditions — no reduction is needed. Consider the following examples: "Does this program terminate in at most 10 steps?" — syntactic (simulate for 10 steps, then decide), so Rice's theorem doesn't apply and the property is decidable. "Does this program compute the squaring function?" — semantic and non-trivial, so Rice's theorem says it is undecidable. "Does this program ever output the digit 7?" — semantic and non-trivial (some programs always output 5, others output 7 at some point), hence undecidable.
The theorem's proof strategy, which you saw in the reduction prerequisite, is to assume a decider for property P and use it to decide the halting problem — a contradiction. The key insight is that you can transform any machine M into a machine M' that behaves exactly like M on some fixed input w, and then behaves in some "P-positive" way if M halts, or some "P-negative" way otherwise. If you could decide whether M' has property P, you could decide whether M halts on w. The construction is generic across all non-trivial semantic properties, which is what makes Rice's theorem so powerful: it collapses an enormous class of questions into a single undecidability result.
The practical upshot for software verification is stark. Questions like "Does this program satisfy its specification?" "Does this function return the correct answer?" "Does this module ever reach an error state?" are all semantic properties of the program's computation. Rice's theorem says none of these can be decided by a general-purpose algorithm, for all programs. This does not mean static analysis and verification tools are useless — they work by restricting to decidable approximations (checking only syntactic patterns, or running on bounded inputs, or analyzing only specific program structures). But it does explain why no tool can be both sound (never misses a bug), complete (never has false positives), and fully general. Understanding Rice's theorem is understanding the fundamental ceiling above which automated program analysis cannot reach.
No topics depend on this one yet.