Solve Timed Logical and Quantitative Reasoning Cases
Epic SystemsSoftware Engineer · Online AssessmentLast updated
Implement a deduction engine that evaluates whether target query statements are definitely true, definitely false, or cannot be determined, given a set of observed facts and unidirectional logical implications.
Problem Description
Automated reasoning systems often evaluate statements under incomplete information. Given a set of ground-truth observations and logical rules, a proposition can be:
"TRUE": It must be true in all valid interpretations."FALSE": It must be false in all valid interpretations (its negation is proven true)."CANNOT_DETERMINE": It is true in at least one valid interpretation and false in at least one valid interpretation.
You are given:
facts: A list of strings representing propositions known to be unconditionally true. If a fact starts with!, its negated proposition is unconditionally false (for example,"!A"means propositionAis false).rules: A list of conditional implication strings in the format"P -> Q", meaning "if propositionPis true, then propositionQmust be true". Note that rules also enforce their contrapositive:"!Q -> !P".queries: A list of proposition strings to evaluate.
Each proposition token is a non-empty alphanumeric string without spaces (e.g., "HospitalA", "BedOccupied"). A token preceded by ! denotes the negation of that proposition. For any query variable X, determine if X is "TRUE", "FALSE", or "CANNOT_DETERMINE".
Assume there are no contradictory premises in facts and rules.
Function Interface
def evaluate_propositions(
facts: list[str],
rules: list[str],
queries: list[str]
) -> list[str]:
pass
Input & Output Format
facts: list of strings, each either"X"or"!X".rules: list of strings, each of the form"X -> Y", whereXandYcan each be either a variable or a negated variable (e.g.,"!A -> B").queries: list of query proposition strings (without!).- Returns: list of strings (
"TRUE","FALSE", or"CANNOT_DETERMINE"), corresponding to each query inqueriesin order.
Constraints
1 <= len(facts) <= 2000 <= len(rules) <= 5001 <= len(queries) <= 200- Variable names consist of 1 to 20 alphanumeric characters.
- The premises are guaranteed to be mutually consistent.
Examples
Example 1
facts = ["NurseOnDuty", "!Admitted"]
rules = [
"NurseOnDuty -> TriageOpen",
"TriageOpen -> Staffed",
"Admitted -> BedAssigned"
]
queries = ["TriageOpen", "BedAssigned", "NurseOnDuty", "Admitted"]
# Output: ["TRUE", "CANNOT_DETERMINE", "TRUE", "FALSE"]
Explanation: NurseOnDuty is true, which implies TriageOpen is true. !Admitted means Admitted is false. However, Admitted -> BedAssigned only specifies what happens if Admitted is true; since Admitted is false, BedAssigned could be true or false (CANNOT_DETERMINE).
Example 2
facts = ["!Discharged"]
rules = [
"Stable -> Discharged"
]
queries = ["Stable"]
# Output: ["FALSE"]
Explanation: By contrapositive, Stable -> Discharged implies !Discharged -> !Stable. Since Discharged is false, Stable must be false.
Hints
Hint 1
Every implication 'A -> B' has an equivalent contrapositive '!B -> !A', so represent each rule as two directed edges in an implication graph.
Hint 2
Double negations cancel out, so '!(!X)' is simply 'X'; parse literals into signed identifiers or integer IDs.
Hint 3
Perform breadth-first or depth-first search starting from the known true literals to find all reachable literals; if literal X is reached, X is TRUE, and if literal !X is reached, X is FALSE.
Follow-up questions
- How would your algorithm detect if the provided facts and rules contained an internal contradiction?
- How would you extend this engine to handle conjunctions in preconditions, such as 'A AND B -> C'?
- If rules were assigned probabilities, how would you compute the lower and upper bounds of belief for each query?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.