Skip to content

Added tt entails algorithm #12902

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions machine_learning/ttentails.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""
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
import re


def safe_eval(expr: str, model: dict[str, bool]) -> 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 safe_eval

"""Safely evaluate propositional logic expression with given model."""
# Replace symbols (like P, Q) with their boolean values
for sym, val in model.items():
expr = re.sub(rf"\b{sym}\b", str(val), expr)
# Allow only True/False, and/or/not operators
allowed = {"True", "False", "and", "or", "not", "(", ")", " "}
if not all(
token in allowed or token.isidentifier() or token in "()"

Check failure on line 22 in machine_learning/ttentails.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (S105)

machine_learning/ttentails.py:22:62: S105 Possible hardcoded password assigned to: "token"
for token in re.split(r"(\W+)", expr)
):
raise ValueError("Unsafe expression detected")
return eval(expr, {"__builtins__": {}}, {})

Check failure on line 26 in machine_learning/ttentails.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (S307)

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


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(safe_eval(sentence, model) for sentence in kb) and not safe_eval(
query, model
):
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