예제 #1
0
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."
예제 #2
0
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.")
예제 #3
0
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)
예제 #4
0
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.")
예제 #5
0
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."
예제 #6
0
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.
예제 #7
0
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)
예제 #8
0
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.
예제 #9
0
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))
예제 #10
0
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))
예제 #11
0
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
예제 #12
0
파일: solve.py 프로젝트: Darriall/geosolver
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