def example_3(): """ Question ID: 1 In the diagram at the right, circle O has a radius of 5, and CE = 2. Diameter AC is perpendicular to chord BD at E. What is the length of BD? :return: """ vh = VariableHandler() A = vh.point('A') B = vh.point('B') C = vh.point('C') D = vh.point('D') E = vh.point('E') O = vh.point('O') CE = vh.line(C, E) AC = vh.line(A, C) BD = vh.line(B, D) cO = vh.circle(O) p1 = vh.apply('RadiusOf', cO) == 5 # Equals(RadiusOf(cO), 5)) p2 = vh.apply('LengthOf', CE) == 2 # Equals(LengthOf(CE), 2) p3 = vh.apply('IsDiameterLineOf', AC, cO) p4 = vh.apply('IsChordOf', BD, cO) p5 = vh.apply('Perpendicular', AC, BD) p6 = vh.apply('PointLiesOnLine', E, AC) # AC intersects BD at E is broken down into two atoms p7 = vh.apply('PointLiesOnLine', E, BD) ps = [p1, p2, p3, p4, p5, p6, p7] ns = NumericSolver(ps, vh) ans = vh.apply('LengthOf', BD) if ns.is_sat(): print ns.evaluate(ans), 8 # 8 is the answer else: print "Given information is not satisfiable."
def example_2(): """ AB is tangent to circle O, AO = BO = 1 and AB = sqrt(2). What is the radius of circle O? :return: """ vh = VariableHandler() O = vh.point('O') A = vh.point('A') B = vh.point('B') AO = vh.line(A, O) BO = vh.line(B, O) AB = vh.line(A, B) # vh.circle() with one argument assumes the radius is an unknown value (i.e. variable). # if you want to define radius, just give it two arguments, e.g. vh.circle(O, r) cO = vh.circle(O) a = vh.apply('LengthOf', AO) b = vh.apply('LengthOf', BO) o = vh.apply('LengthOf', AB) p1 = a == 1 p2 = b == 1 p3 = o == np.sqrt(2) p4 = vh.apply('Tangent', AB, cO) ns = NumericSolver([p1, p2, p3, p4], vh) ans = vh.apply('RadiusOf', cO) if ns.is_sat(): print ns.evaluate(ans), 1 / np.sqrt(2) # the latter is the true answer else: print("Given information is not satisfiable.")
def test_solving(): pk = 973 questions = geoserver_interface.download_questions(pk) question = questions.values()[0] label_data = geoserver_interface.download_labels(pk)[pk] diagram = open_image(question.diagram_path) graph_parse = diagram_to_graph_parse(diagram) match_parse = parse_match_from_known_labels(graph_parse, label_data) AB = v('AB', 'line') AC = v('AC', 'line') BC = v('BC', 'line') ED = v('ED', 'line') AE = v('AE', 'line') E = v('E', 'point') D = v('D', 'point') x = v('x', 'number') p1 = f('LengthOf', AB) == f('LengthOf', AC) p2 = f('IsMidpointOf', E, AB) p3 = f('IsMidpointOf', D, AC) p4 = f('LengthOf', AE) == x p5 = f('LengthOf', ED) == 4 qn = f('LengthOf', BC) confident_atoms = parse_confident_formulas(graph_parse) text_atoms = ground_formula_nodes(match_parse, [p1, p2, p3, p4, p5]) atoms = confident_atoms + text_atoms grounded_qn = ground_formula_nodes(match_parse, [qn])[0] ns = NumericSolver(atoms) print ns.evaluate(grounded_qn)
def example_2(): """ AB is tangent to circle O, AO = BO = 1 and AB = sqrt(2). What is the radius of circle O? :return: """ vh = VariableHandler() O = vh.point('O') A = vh.point('A') B = vh.point('B') AO = vh.line(A, O) BO = vh.line(B, O) AB = vh.line(A, B) # vh.circle() with one argument assumes the radius is an unknown value (i.e. variable). # if you want to define radius, just give it two arguments, e.g. vh.circle(O, r) cO = vh.circle(O) a = vh.apply('LengthOf', AO) b = vh.apply('LengthOf', BO) o = vh.apply('LengthOf', AB) p1 = a == 1 p2 = b == 1 p3 = o == np.sqrt(2) p4 = vh.apply('Tangent', AB, cO) ns = NumericSolver([p1, p2, p3, p4], vh) ans = vh.apply('RadiusOf', cO) if ns.is_sat(): print ns.evaluate(ans), 1/np.sqrt(2) # the latter is the true answer else: print("Given information is not satisfiable.")
def example_1(): """ AB perpendicular to BC, AB = x, and BC = 4. Is CA = sqrt(x^2+16) a correct answer? :return: """ vh = VariableHandler() x = vh.number('x') A = vh.point('A') B = vh.point('B') C = vh.point('C') AB = vh.line(A, B) BC = vh.line(B, C) CA = vh.line(C, A) c = vh.apply('LengthOf', AB) a = vh.apply('LengthOf', BC) b = vh.apply('LengthOf', CA) p1 = a == 4 p2 = c == x p3 = vh.apply('Perpendicular', AB, BC) q1 = b == (16 + x**2)**0.5 q2 = b == x**2 ns = NumericSolver([p1, p2, p3], vh) print(ns.find_assignment(q1)) # find_assignment simply analyzes whether the query relation can be satisfied print(ns.query_invar(q1)) # query_invar analyzes whether the query relation must hold true print(ns.find_assignment(q2)) # this is satisfiable; there exists x that satisfies q2. print(ns.query_invar(q2)) # this is False because q2 is not true for all possible x.
def example_1(): """ AB perpendicular to BC, AB = x, and BC = 4. Is CA = sqrt(x^2+16) a correct answer? :return: """ vh = VariableHandler() x = vh.number('x') A = vh.point('A') B = vh.point('B') C = vh.point('C') AB = vh.line(A, B) BC = vh.line(B, C) CA = vh.line(C, A) c = vh.apply('LengthOf', AB) a = vh.apply('LengthOf', BC) b = vh.apply('LengthOf', CA) p1 = a == 4 p2 = c == x p3 = vh.apply('Perpendicular', AB, BC) q1 = b == (16 + x**2)**0.5 q2 = b == x**2 ns = NumericSolver([p1, p2, p3], vh) print( ns.find_assignment(q1) ) # find_assignment simply analyzes whether the query relation can be satisfied print(ns.query_invar(q1) ) # query_invar analyzes whether the query relation must hold true print(ns.find_assignment(q2) ) # this is satisfiable; there exists x that satisfies q2. print(ns.query_invar(q2) ) # this is False because q2 is not true for all possible x.
def example_0(): """ AB = x, BC = 3, CA = 4. Is an answer x=5, x=8 possible? :return: """ vh = VariableHandler() x = vh.number('x') A = vh.point('A') B = vh.point('B') C = vh.point('C') AB = vh.line(A, B) BC = vh.line(B, C) CA = vh.line(C, A) c = vh.apply('LengthOf', AB) a = vh.apply('LengthOf', BC) b = vh.apply('LengthOf', CA) p1 = a == 3 p2 = b == 4 p3 = c == x q1 = x == 8 q2 = x == 5 ns = NumericSolver([p1, p2, p3], vh) print(ns.find_assignment(q1)) print(ns.find_assignment(q2))
def solve(given_formulas, choice_formulas=None, assignment=None): """ :param list true_formulas: :param dict choice_formulas: :return: """ start_time = time.time() out = {} #1. Find query formula in true formulas true_formulas = [] query_formula = None for formula in given_formulas: assert isinstance(formula, FormulaNode) if formula.has_signature("What") or formula.has_signature( "Which") or formula.has_signature("Find"): if query_formula is not None: logging.warning("More than one query formula.") query_formula = formula else: true_formulas.append(formula) if query_formula is None: raise Exception("No query formula.") elif query_formula.has_signature("What"): if choice_formulas is None: ns = NumericSolver(given_formulas, assignment=assignment) ns.solve() out = ns.assignment['What'] else: ns = NumericSolver(given_formulas, assignment=assignment) ns.solve() for key, choice_formula in choice_formulas.iteritems(): equal_formula = FormulaNode( signatures['Equals'], [ns.assignment['What'], choice_formula]) out[key] = ns.evaluate(equal_formula) """ ns = NumericSolver(true_formulas) ns.solve() for key, choice_formula in choice_formulas.iteritems(): # print query_formula.children[1], ns.evaluate(query_formula.children[1]) # print choice_formula, ns.evaluate(choice_formula) tester = lambda node: isinstance(node, FormulaNode) and node.signature.id == "What" getter = lambda node: choice_formula replaced_formula = query_formula.replace_node(tester, getter) # print replaced_formula out[key] = ns.evaluate(replaced_formula) """ # display_entities(ns) elif query_formula.has_signature("Find"): ns = NumericSolver(true_formulas, assignment=assignment) ns.solve() # display_entities(ns) if choice_formulas is None: # No choice given; need to find the answer! out = ns.evaluate(query_formula.children[0]) else: for key, choice_formula in choice_formulas.iteritems(): replaced_formula = FormulaNode( signatures['Equals'], [query_formula.children[0], choice_formula]) out[key] = ns.evaluate(replaced_formula) # display_entities(ns) elif query_formula.has_signature("Which"): ns = NumericSolver(true_formulas, assignment=assignment) ns.solve() for key, choice_formula in choice_formulas.iteritems(): # print query_formula.children[1], ns.evaluate(query_formula.children[1]) # print choice_formula, ns.evaluate(choice_formula) tester = lambda node: node.signature.id == "Which" getter = lambda node: choice_formula replaced_formula = query_formula.replace_node(tester, getter) out[key] = ns.evaluate(replaced_formula) # this won't be executed! elif query_formula.has_signature("Which"): tester = lambda node: isinstance(node, FormulaNode ) and node.signature.id == "Which" for choice, choice_formula in choice_formulas.iteritems(): getter = lambda node: choice_formula replaced_formula = query_formula.replace_node(tester, getter) all_formulas = true_formulas + [replaced_formula] ns = NumericSolver(all_formulas) out[choice] = ns.evaluate(replaced_formula) print out[choice] #display_entities(ns) else: raise Exception() end_time = time.time() delta_time = end_time - start_time print "%.2f seconds" % delta_time return out
def solve(given_formulas, choice_formulas=None, assignment=None): """ :param list true_formulas: :param dict choice_formulas: :return: """ start_time = time.time() out = {} #1. Find query formula in true formulas true_formulas = [] query_formula = None for formula in given_formulas: assert isinstance(formula, FormulaNode) if formula.has_signature("What") or formula.has_signature("Which") or formula.has_signature("Find"): if query_formula is not None: logging.warning("More than one query formula.") query_formula = formula else: true_formulas.append(formula) if query_formula is None: raise Exception("No query formula.") elif query_formula.has_signature("What"): if choice_formulas is None: ns = NumericSolver(given_formulas, assignment=assignment) ns.solve() out = ns.assignment['What'] else: ns = NumericSolver(given_formulas, assignment=assignment) ns.solve() for key, choice_formula in choice_formulas.iteritems(): equal_formula = FormulaNode(signatures['Equals'], [ns.assignment['What'], choice_formula]) out[key] = ns.evaluate(equal_formula) """ ns = NumericSolver(true_formulas) ns.solve() for key, choice_formula in choice_formulas.iteritems(): # print query_formula.children[1], ns.evaluate(query_formula.children[1]) # print choice_formula, ns.evaluate(choice_formula) tester = lambda node: isinstance(node, FormulaNode) and node.signature.id == "What" getter = lambda node: choice_formula replaced_formula = query_formula.replace_node(tester, getter) # print replaced_formula out[key] = ns.evaluate(replaced_formula) """ # display_entities(ns) elif query_formula.has_signature("Find"): ns = NumericSolver(true_formulas, assignment=assignment) ns.solve() # display_entities(ns) if choice_formulas is None: # No choice given; need to find the answer! out = ns.evaluate(query_formula.children[0]) else: for key, choice_formula in choice_formulas.iteritems(): replaced_formula = FormulaNode(signatures['Equals'], [query_formula.children[0], choice_formula]) out[key] = ns.evaluate(replaced_formula) # display_entities(ns) elif query_formula.has_signature("Which"): ns = NumericSolver(true_formulas, assignment=assignment) ns.solve() for key, choice_formula in choice_formulas.iteritems(): # print query_formula.children[1], ns.evaluate(query_formula.children[1]) # print choice_formula, ns.evaluate(choice_formula) tester = lambda node: node.signature.id == "Which" getter = lambda node: choice_formula replaced_formula = query_formula.replace_node(tester, getter) out[key] = ns.evaluate(replaced_formula) # this won't be executed! elif query_formula.has_signature("Which"): tester = lambda node: isinstance(node, FormulaNode) and node.signature.id == "Which" for choice, choice_formula in choice_formulas.iteritems(): getter = lambda node: choice_formula replaced_formula = query_formula.replace_node(tester, getter) all_formulas = true_formulas + [replaced_formula] ns = NumericSolver(all_formulas) out[choice] = ns.evaluate(replaced_formula) print out[choice] #display_entities(ns) else: raise Exception() end_time = time.time() delta_time = end_time - start_time print "%.2f seconds" % delta_time return out