Skip to content
49 changes: 49 additions & 0 deletions machine_learning/ttentails.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
TT-ENTAILS Algorithm (Propositional Logic)
Reference: [Russell & Norvig, Artificial Intelligence: A Modern Approach, Ch. 7](https://aima.cs.berkeley.edu/)
Wikipedia: [Entailment](https://en.wikipedia.org/wiki/Entailment)

This algorithm checks if a knowledge base (KB) entails a query sentence (a)
using truth tables. Returns True if KB entails a, False otherwise.
"""

import itertools

Check failure on line 10 in machine_learning/ttentails.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

machine_learning/ttentails.py:10:1: I001 Import block is un-sorted or un-formatted

def tt_entails(kb: list[str], query: str, symbols: list[str]) -> bool:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file machine_learning/ttentails.py, please provide doctest for the function tt_entails

"""
Check if the knowledge base entails the query using truth tables.

Args:
kb (List[str]): List of propositional sentences in KB as strings
query (str): Query sentence to test entailment
symbols (List[str]): List of all propositional symbols used

Returns:
bool: True if KB entails query, False otherwise

Example:
tt_entails(["P or Q"], "Q", ["P","Q"])

"""
for values in itertools.product([True, False], repeat=len(symbols)):
model: dict[str, bool] = dict(zip(symbols, values))
# Check if KB is true under this model
# # If query is false in this model, KB does not entail query
if all(eval(sentence, {}, model) for sentence in kb) and not eval(query, {}, model):

Check failure on line 32 in machine_learning/ttentails.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

machine_learning/ttentails.py:32:89: E501 Line too long (92 > 88)

Check failure on line 32 in machine_learning/ttentails.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (S307)

machine_learning/ttentails.py:32:70: S307 Use of possibly insecure function; consider using `ast.literal_eval`

Check failure on line 32 in machine_learning/ttentails.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (S307)

machine_learning/ttentails.py:32:16: S307 Use of possibly insecure function; consider using `ast.literal_eval`
return False
return True


# Example usage
if __name__ == "__main__":
# Example 1: KB entails query → should return True
symbols = ["P", "Q"]
kb = ["P or Q", "not P or Q"] # KB says P or Q is True, and not P or Q is True
query = "Q" # Query: Is Q True?
print("Does KB entail query? : ", tt_entails(kb, query, symbols))

# Example 2: KB does NOT entail query → should return False
symbols2 = ["P", "Q"]
kb2 = ["P"] # KB says only P is True
query2 = "Q" # Query asks if Q is True
print("Does KB2 entail query2? : ", tt_entails(kb2, query2, symbols2))
Loading