88"""
99
1010import itertools
11+ import re
12+
13+
14+ def safe_eval (expr : str , model : dict [str , bool ]) -> bool :
15+ """Safely evaluate propositional logic expression with given model."""
16+ # Replace symbols (like P, Q) with their boolean values
17+ for sym , val in model .items ():
18+ expr = re .sub (rf'\b{ sym } \b' , str (val ), expr )
19+ # Allow only True/False, and/or/not operators
20+ allowed = {"True" , "False" , "and" , "or" , "not" , "(" , ")" , " " }
21+ if not all (token in allowed or token .isidentifier () or token in "()" for token in re .split (r'(\W+)' , expr )):
22+ raise ValueError ("Unsafe expression detected" )
23+ return eval (expr , {"__builtins__" : {}}, {})
24+
1125
1226def tt_entails (kb : list [str ], query : str , symbols : list [str ]) -> bool :
1327 """
@@ -29,7 +43,7 @@ def tt_entails(kb: list[str], query: str, symbols: list[str]) -> bool:
2943 model : dict [str , bool ] = dict (zip (symbols , values ))
3044 # Check if KB is true under this model
3145 # # If query is false in this model, KB does not entail query
32- if all (eval (sentence , {}, model ) for sentence in kb ) and not eval (query , {} , model ):
46+ if all (safe_eval (sentence , model ) for sentence in kb ) and not safe_eval (query , model ):
3347 return False
3448 return True
3549
0 commit comments