Skip to content

Metadata Card

  • Prerequisites: ch01 Search Algorithms, Vol 10 Probability Theory
  • Estimated time: 45 minutes
  • Core difficulty: Advanced
  • Reading mode: High focus
  • Completion: Able to build a logical reasoning system, represent constraint satisfaction problems, understand Bayesian network inference mechanisms

Your Progress

At the first workbench in the Model Workshop, you learned search—finding paths in a known space.

But Ahua's next letter asked: "What if the knowledge itself is incomplete?" You put down the letter, looking at the second workbench. There's another set of tools here: logical reasoning, probabilistic networks—not finding paths, but making judgments under uncertainty.

Your Task

Search assumes you can enumerate all states. But in reality, knowledge is often fragmented and noisy. You need a "representation" to encapsulate knowledge, paired with a "reasoning" mechanism to derive new conclusions. This chapter follows three paths: logic (deterministic), CSP (constraint-driven), and Bayesian networks (probability-driven).

Chapter Layers

  • Required: Propositional logic reasoning, constraint satisfaction problems, Bayesian network representation
  • Optional: Exact and approximate inference in Bayesian networks
  • Advanced: Viewing knowledge representation as a search space design problem

Breaking Through · Tracing the Origin

You see a rule: "If it rains, the ground gets wet." Now the ground is wet—you conclude: it rained. Is this reasoning correct? It depends on an implicit assumption: no other reason could make the ground wet. You've done the reverse of Modus Ponens—but in real-world logic, this is the "affirming the consequent" fallacy.

A truly reliable knowledge system not only reasons but also evaluates the reliability of its reasoning. This is the starting point of this chapter.

Propositional Logic and Reasoning

Propositional logic is the most basic knowledge representation language. Each proposition takes a true or false value, combined with logical connectives (→, ∧, ∨, ¬).

The reasoning workbench in the Model Workshop starts with the simplest rule chains. Forward chaining repeatedly applies rules from known facts until saturation—this is exactly the 'if-then' reasoning you use in complex condition checks.

python
# Simple rule-based reasoning engine
rules = [
    ("rain", "ground_wet"),       # rain → ground_wet
    ("ground_wet", "slippery"),   # ground_wet → slippery
]

def forward_chain(facts, rules):
    """Forward chaining inference: derive new facts from known facts"""
    known = set(facts)
    changed = True
    while changed:
        changed = False
        for premise, conclusion in rules:
            if premise in known and conclusion not in known:
                known.add(conclusion)
                changed = True
    return known

facts = forward_chain(["rain"], rules)
print(facts)  # {'rain', 'ground_wet', 'slippery'}

Forward chaining starts from known facts and applies rules repeatedly until saturation. Backward chaining starts from the goal and searches in reverse: to prove "slippery," you need to prove "ground_wet," which requires proving "rain."

Constraint Satisfaction Problems

Many real-world reasoning problems are constraint-driven. For example, scheduling: a teacher can't teach two classes at the same time, each course has a fixed classroom capacity—you need to find an assignment satisfying all constraints.

CSP is modeled with the triple of variables, domains, and constraints:

Backtracking search for constraint satisfaction problems is another classic framework. You assign values to all variables, checking each time whether the assignment conflicts with existing assignments—it's search with constraints.

python
from itertools import product

def backtrack_search(variables, domains, constraints):
    """Backtracking search for solving CSP"""
    assignment = {}

    def consistent(var, value, assignment):
        return all(
            constraint(var, value, v, assignment[v])
            for v in assignment
            for constraint in constraints.get((var, v), [])
        )

    def search(assignment):
        if len(assignment) == len(variables):
            return assignment
        var = next(v for v in variables if v not in assignment)
        for value in domains[var]:
            if consistent(var, value, assignment):
                assignment[var] = value
                result = search(assignment)
                if result:
                    return result
                del assignment[var]
        return None

    return search({})

Example: map coloring—adjacent regions can't share the same color.

python
variables = ['WA', 'NT', 'SA', 'Q', 'NSW', 'V', 'T']
domains = {v: ['R', 'G', 'B'] for v in variables}
constraints = {}
pairs = [('WA','NT'),('WA','SA'),('NT','SA'),('NT','Q'),
         ('SA','Q'),('SA','NSW'),('SA','V'),('Q','NSW'),
         ('NSW','V')]
for a, b in pairs:
    constraints[(a,b)] = [lambda x, xv, y, yv: xv != yv]

print(backtrack_search(variables, domains, constraints))
# {'WA': 'R', 'NT': 'G', 'SA': 'B', 'Q': 'R', 'NSW': 'G', 'V': 'R', 'T': 'R'}

The difficulty of CSP isn't expressiveness—it's search efficiency. Variable ordering and value ordering heuristics (MRV, degree heuristic, least-constraining value) can massively impact backtracking counts.

Bayesian Networks

Logical systems can't handle uncertainty. Bayesian networks use a graph structure to represent probabilistic dependencies between variables: nodes are random variables, directed edges represent "direct influence," and each node has a conditional probability table.

Logical reasoning only deals with a deterministic world: if it doesn't rain, the ground isn't wet. But reality isn't like that—a 'sprinkler' can also make the ground wet. Bayesian networks use probability to represent multiple possible causes simultaneously.

python
# A simple Bayesian network inference
# Events: rain → ground_wet
#         sprinkler → ground_wet
# rain and sprinkler are independent

import numpy as np

class BayesNet:
    def __init__(self):
        self.nodes = {}
        self.cpts = {}

    def add_node(self, name, parents, prob_table):
        self.nodes[name] = parents
        self.cpts[name] = prob_table

    # Given evidence, compute marginal probability by enumeration

def enumeration_ask(query, evidence, net):
    """Enumerate all hidden variables to compute P(query | evidence)"""
    hidden = [v for v in net.nodes if v not in evidence and v != query]
    return _enumerate_all(net.variables(), evidence, hidden, net)

# Variable elimination is more efficient for practical inference
def variable_elimination(net, query, evidence, ordering):
    """Variable elimination method"""
    factors = []
    for var in net.variables():
        factor = net.make_factor(var, evidence)
        factors.append(factor)
    for var in ordering:
        if var not in query and var not in evidence:
            factors = _sum_out(var, factors)
    result = _normalize(_pointwise_product(factors))
    return result

Exact inference in Bayesian networks is NP-hard (variable elimination has exponential complexity in the worst case), so large networks typically use approximate inference methods like Gibbs sampling or likelihood weighting.

Common Pitfalls

  • The "closed-world assumption" in logical systems: what's not proven true is considered false? Or not proven true is unknown? In AI terms, this is default negation vs. open world.
  • In CSP, consistency doesn't equal satisfiability—node consistency and arc consistency don't guarantee a solution exists.
  • The conditional independence assumption in Bayesian networks is crucial—if your conditional probability table doesn't satisfy the graph structure, inference will be wrong.
  • The directionality of Bayesian networks implies causality, but correlation doesn't equal causation—two observed correlated variables might share a third unobserved common cause.

Pass Challenges

  • Warm-up (15 min): Implement a backward chaining engine. Input the goal "slippery," output which initial facts are needed.
  • Challenge (30 min): Use CSP to implement a simple Sudoku solver (9x9, backtracking + MRV heuristic).
  • Observation: Build a 3-node Bayesian network (A→B→C), given P(A), P(B|A), P(C|B), compute P(B|C=1). Compare the steps needed for enumeration vs. variable elimination.

Traveler's Notes

Knowledge representation determines what an AI system can "think," and the reasoning mechanism determines "how it thinks." Logic provides guarantees, probability provides flexibility—their combination is the foundation of truly intelligent reasoning.

-> Next Chapter Preview

Search and reasoning alone aren't enough—agents need to learn from environmental interaction without complete knowledge. That's what reinforcement learning does.

Built with VitePress | Software Systems Atlas