From 969b31354e582fa93513bee36f84e1090f7dc337 Mon Sep 17 00:00:00 2001 From: "mahidhiman@21" Date: Mon, 18 Aug 2025 23:16:02 +0530 Subject: [PATCH 1/7] Add TT-ENTAILS algorithm (propositional logic) with examples --- machine_learning/TT_Entails.py | 52 ++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 machine_learning/TT_Entails.py diff --git a/machine_learning/TT_Entails.py b/machine_learning/TT_Entails.py new file mode 100644 index 000000000000..d8798a2ea4fc --- /dev/null +++ b/machine_learning/TT_Entails.py @@ -0,0 +1,52 @@ +""" +TT-ENTAILS Algorithm (Propositional Logic) +Reference: Russell & Norvig, Artificial Intelligence: A Modern Approach + +This algorithm checks if a knowledge base (KB) entails a query sentence (α) +using truth tables. Returns True if KB entails α, False otherwise. +""" + +import itertools +from typing import List, Dict + +def tt_entails(kb: List[str], query: str, symbols: List[str]) -> bool: + """ + 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 all(eval(sentence, {}, model) for sentence in kb): + # If query is false in this model, KB does not entail query + if not 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)) + + + From 518f00336e56b97e5eed1bbededdbffc6d7b64be Mon Sep 17 00:00:00 2001 From: "mahidhiman@21" Date: Mon, 18 Aug 2025 23:27:43 +0530 Subject: [PATCH 2/7] Rename file to lowercase without dash to follow repo conventions --- machine_learning/ttentails.py | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 machine_learning/ttentails.py diff --git a/machine_learning/ttentails.py b/machine_learning/ttentails.py new file mode 100644 index 000000000000..d8798a2ea4fc --- /dev/null +++ b/machine_learning/ttentails.py @@ -0,0 +1,52 @@ +""" +TT-ENTAILS Algorithm (Propositional Logic) +Reference: Russell & Norvig, Artificial Intelligence: A Modern Approach + +This algorithm checks if a knowledge base (KB) entails a query sentence (α) +using truth tables. Returns True if KB entails α, False otherwise. +""" + +import itertools +from typing import List, Dict + +def tt_entails(kb: List[str], query: str, symbols: List[str]) -> bool: + """ + 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 all(eval(sentence, {}, model) for sentence in kb): + # If query is false in this model, KB does not entail query + if not 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)) + + + From 62d616f80c0bca3a7fe8766d9ead31429597a735 Mon Sep 17 00:00:00 2001 From: "mahidhiman@21" Date: Mon, 18 Aug 2025 23:34:54 +0530 Subject: [PATCH 3/7] Add TT-ENTAILS algorithm with examples and references --- machine_learning/TT_Entails.py | 52 ---------------------------------- machine_learning/ttentails.py | 3 +- 2 files changed, 2 insertions(+), 53 deletions(-) delete mode 100644 machine_learning/TT_Entails.py diff --git a/machine_learning/TT_Entails.py b/machine_learning/TT_Entails.py deleted file mode 100644 index d8798a2ea4fc..000000000000 --- a/machine_learning/TT_Entails.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -TT-ENTAILS Algorithm (Propositional Logic) -Reference: Russell & Norvig, Artificial Intelligence: A Modern Approach - -This algorithm checks if a knowledge base (KB) entails a query sentence (α) -using truth tables. Returns True if KB entails α, False otherwise. -""" - -import itertools -from typing import List, Dict - -def tt_entails(kb: List[str], query: str, symbols: List[str]) -> bool: - """ - 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 all(eval(sentence, {}, model) for sentence in kb): - # If query is false in this model, KB does not entail query - if not 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)) - - - diff --git a/machine_learning/ttentails.py b/machine_learning/ttentails.py index d8798a2ea4fc..e54e1acd65c5 100644 --- a/machine_learning/ttentails.py +++ b/machine_learning/ttentails.py @@ -1,6 +1,7 @@ """ TT-ENTAILS Algorithm (Propositional Logic) -Reference: Russell & Norvig, Artificial Intelligence: A Modern Approach +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 (α) using truth tables. Returns True if KB entails α, False otherwise. From fe06a03e7a6f699bef3ca5de78d76bce068204a8 Mon Sep 17 00:00:00 2001 From: "mahidhiman@21" Date: Mon, 18 Aug 2025 23:50:33 +0530 Subject: [PATCH 4/7] Fix ruff/pre-commit issues: docstrings, typing, imports, nested if, safe eval comment --- machine_learning/ttentails.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/machine_learning/ttentails.py b/machine_learning/ttentails.py index e54e1acd65c5..ea1355ee81eb 100644 --- a/machine_learning/ttentails.py +++ b/machine_learning/ttentails.py @@ -3,14 +3,13 @@ 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 (α) -using truth tables. Returns True if KB entails α, False otherwise. +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 -from typing import List, Dict -def tt_entails(kb: List[str], query: str, symbols: List[str]) -> bool: +def tt_entails(kb: list[str], query: str, symbols: list[str]) -> bool: """ Check if the knowledge base entails the query using truth tables. @@ -27,12 +26,11 @@ def tt_entails(kb: List[str], query: str, symbols: List[str]) -> bool: """ for values in itertools.product([True, False], repeat=len(symbols)): - model: Dict[str, bool] = dict(zip(symbols, values)) + model: dict[str, bool] = dict(zip(symbols, values)) # Check if KB is true under this model - if all(eval(sentence, {}, model) for sentence in kb): - # If query is false in this model, KB does not entail query - if not eval(query, {}, model): - return False + # # 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): + return False return True # Example usage From 91e6fe6674e589a8e9d293442eb0c52e8f5bf1c1 Mon Sep 17 00:00:00 2001 From: "mahidhiman@21" Date: Tue, 19 Aug 2025 00:01:08 +0530 Subject: [PATCH 5/7] add TT-entails algorithm --- machine_learning/ttentails.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/machine_learning/ttentails.py b/machine_learning/ttentails.py index ea1355ee81eb..ffd6526a72ec 100644 --- a/machine_learning/ttentails.py +++ b/machine_learning/ttentails.py @@ -20,8 +20,8 @@ def tt_entails(kb: list[str], query: str, symbols: list[str]) -> bool: Returns: bool: True if KB entails query, False otherwise - - Example: + + Example: tt_entails(["P or Q"], "Q", ["P","Q"]) """ @@ -33,19 +33,17 @@ def tt_entails(kb: list[str], query: str, symbols: list[str]) -> bool: 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? + 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 + 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)) - - - From e06f29f6aad673cc4516e30f4813fd76ed7f0339 Mon Sep 17 00:00:00 2001 From: "mahidhiman@21" Date: Tue, 19 Aug 2025 00:11:35 +0530 Subject: [PATCH 6/7] add TT-entails algorithm --- machine_learning/ttentails.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/machine_learning/ttentails.py b/machine_learning/ttentails.py index ffd6526a72ec..491aaa838e36 100644 --- a/machine_learning/ttentails.py +++ b/machine_learning/ttentails.py @@ -8,6 +8,20 @@ """ import itertools +import re + + +def safe_eval(expr: str, model: dict[str, bool]) -> bool: + """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 "()" for token in re.split(r'(\W+)', expr)): + raise ValueError("Unsafe expression detected") + return eval(expr, {"__builtins__": {}}, {}) + def tt_entails(kb: list[str], query: str, symbols: list[str]) -> bool: """ @@ -29,7 +43,7 @@ def tt_entails(kb: list[str], query: str, symbols: list[str]) -> bool: 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): + if all(safe_eval(sentence, model) for sentence in kb) and not safe_eval(query, model): return False return True From 67e9df99a237f79386533a44def14f2ed68bb782 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 18:47:47 +0000 Subject: [PATCH 7/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- machine_learning/ttentails.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/machine_learning/ttentails.py b/machine_learning/ttentails.py index 491aaa838e36..f9667cca7712 100644 --- a/machine_learning/ttentails.py +++ b/machine_learning/ttentails.py @@ -15,10 +15,13 @@ def safe_eval(expr: str, model: dict[str, bool]) -> bool: """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) + 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 "()" for token in re.split(r'(\W+)', expr)): + if not all( + token in allowed or token.isidentifier() or token in "()" + for token in re.split(r"(\W+)", expr) + ): raise ValueError("Unsafe expression detected") return eval(expr, {"__builtins__": {}}, {}) @@ -43,7 +46,9 @@ def tt_entails(kb: list[str], query: str, symbols: list[str]) -> bool: 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): + if all(safe_eval(sentence, model) for sentence in kb) and not safe_eval( + query, model + ): return False return True