.. include:: ../global.rst ****************************************** Python vs. Prolog: The Quest for Logic ****************************************** ================================================== "How" vs. "What" ================================================== As a Python developer, you are a **Chef**. You write a recipe: "First chop this, then sauté that, if it smells burnt, lower the heat." This is **Imperative Programming**. You manage the state of the kitchen every step of the way. In **Declarative Programming** (like Prolog), you are a **Travel Agent**. You describe the desired outcome: "I want a vacation that is tropical, under $2,000, and has a gym." You don't tell the agent which flight paths to take; you describe the constraints, and the system finds a solution that fits. --- The Building Blocks ============================= While Python relies on functions that return values, Prolog relies on a **Knowledge Base** built of three things: 1. **Facts (The Data)** Facts are "atoms" of truth. They don't need logic to be true; they just are. * **Prolog:** ``is_wizard(gandalf).`` * **Python equivalent:** A value in a dictionary or a row in a database. 2. **Rules (The Logic)** Rules use the "implication" operator ``:-``, which translates to **"is true if"**. * ``can_cast_spell(X) :- is_wizard(X), has_staff(X).`` * *Translation:* "X can cast a spell **if** X is a wizard **and** X has a staff." 3. **Unification (The Matching Engine)** In Python, ``=`` is assignment (putting a value in a box). In Prolog, it is **Unification**. It asks: "Can I make these two things look the same?" If you ask Prolog ``wizard(X) = wizard(gandalf)``, it concludes that $X = gandalf$ to make the statement true. --- Comparing the Logic: The "Quest Party" Example ============================================== Let's build a system to determine who is in a "party" together based on their current location. The Python Way (Imperative) --------------------------- In Python, we have to manually iterate and filter. We are responsible for the "search" logic. .. code-block:: python # The Data locations = { "Frodo": "Shire", "Samwise": "Shire", "Merry": "Shire", "Aragorn": "Rivendell", } def get_party_members(location_name): party = [] for person, loc in locations.items(): if loc == location_name: party.append(person) return party # Usage: print(f"People in the Shire: {get_party_members('Shire')}") The Prolog Way (Declarative) ---------------------------- In Prolog, we define the relationships. The "search" is built into the language engine itself via **Backtracking**. .. code-block:: prolog % Facts at_location(frodo, shire). at_location(samwise, shire). at_location(merry, shire). at_location(aragorn, rivendell). % The Rule: X and Y are in a party if they are at the same place P % and X is not the same person as Y. in_party(X, Y) :- at_location(X, P), at_location(Y, P), X \= Y. --- Backtracking and Reversibility ================================================ This is where the magic happens. In Python, your ``get_party_members`` function is a one-way street: it takes a **location** and returns **people**. In Prolog, the *exact same code* works in any direction: 1. **Who is in Frodo's party?** Query: ``?- in_party(frodo, X).`` Result: ``X = samwise``, ``X = merry``. 2. **Find every possible pair in any party:** Query: ``?- in_party(X, Y).`` Result: (Prolog lists every valid combination it can find by "Backtracking"). 3. **Is there anyone in a party at the Shire?** Query: ``?- in_party(X, Y), at_location(X, shire).`` Prolog uses **Backtracking**: if it picks a person who has no party members, it "rewinds" its decision, goes back to the last successful step, and tries a different path automatically. Summary Comparison ================== .. list-table:: :widths: 20 40 40 :header-rows: 1 * - Feature - Python (Imperative) - Prolog (Declarative) * - **Primary Tool** - Functions & Objects - Facts & Rules * - **Execution** - Line-by-line (Step-by-step) - Resolution & Backtracking * - **Variables** - Can change (Mutable) - Once bound, they stay (Immutable) * - **Success/Failure** - Returns a value or Error - Finds a solution or returns ``false`` .. note:: Python is a "General Purpose" powerhouse—best for web servers, apps, and data science. Prolog is a specialist—best for scheduling, AI logic puzzles, and complex constraint-solving. ---