Ejemplo n.º 1
0
def _ground_formula(match_parse, formula, threshold=0.5):
    if formula.is_leaf():
        if formula.is_grounded(
                match_parse.graph_parse.core_parse.variable_assignment.keys()):
            out = formula
        else:
            out = _ground_variable(match_parse, formula)
    else:
        children = [
            _ground_formula(match_parse, child) for child in formula.children
        ]
        if isinstance(formula, SetNode):
            if False:  #formula.children[0].signature.return_type == 'truth':
                new_children = []
                for child in children:
                    if child.has_constant():
                        new_children.append(child)
                    else:
                        tv = match_parse.graph_parse.core_parse.evaluate(child)
                        if tv.conf > threshold:
                            new_children.append(child)
                out = SetNode(new_children)
            else:
                out = SetNode(children)
        else:
            out = FormulaNode(formula.signature, children)
    final = _apply_distribution(out)
    return final
    def add(self, formula_node, assignment=None):
        if assignment is None:
            assignment = {}
        if not isinstance(formula_node, Node):
            return formula_node

        if formula_node.is_leaf():
            assert isinstance(formula_node, FormulaNode)
            sig = formula_node.signature
            if isinstance(sig, FunctionSignature):
                return formula_node
            elif formula_node.signature.id in self.named_entities:
                return self.named_entities[sig.id]
            elif formula_node.return_type == "point":
                init = None
                if sig.id in assignment:
                    init = assignment[sig.id]
                return self.point(sig.id, init)
            elif formula_node.return_type == "number":
                init = None
                if sig.id in assignment:
                    init = assignment[sig.id]
                return self.number(sig.id, init)
            else:
                raise Exception()
        else:
            children = [self.add(child) for child in formula_node.children]
            if isinstance(formula_node, FormulaNode):
                formula = FormulaNode(formula_node.signature, children)
                if formula_node.signature.id in ['Line', 'Circle']:
                    self.entities.append(formula)
            else:
                formula = SetNode(children)
            return formula
Ejemplo n.º 3
0
    def tester(node):
        if node.signature.valence == 2 and node.is_singular():
            child_node = node.children[0]
            if child_node.signature in graph.nodes() and len(
                    graph.edges(child_node.signature)) == 1:
                nbr = graph[child_node.signature].keys()[0]
                if is_valid_relation(node.signature, nbr, 1):
                    nbr_node = FormulaNode(nbr, [])
                    return FormulaNode(node.signature,
                                       [node.children[0], nbr_node])

            # insert dummy variable
            nbr = VariableSignature("dummy",
                                    node.signature.arg_types[1],
                                    name=node.signature.arg_types[1])
            nbr_node = FormulaNode(nbr, [])
            return FormulaNode(node.signature, [node.children[0], nbr_node])

        if node.signature not in firsts:
            return None
        if node.parent is None:
            raise Exception
        if isinstance(node.parent,
                      FormulaNode) and (node.parent.signature.valence == 1
                                        or node.parent.is_plural()):
            args = [
                FormulaNode(nbr, []) for nbr in graph[node.signature]
                if is_valid_relation(node.parent.signature, nbr, node.index)
            ]
            if len(args) == 0:
                return None
            return SetNode([node] + args)
        return None
Ejemplo n.º 4
0
def _apply_distribution_helper(node):
    if not isinstance(node, FormulaNode) or len(node.children) == 0:
        return node
    node = FormulaNode(
        node.signature,
        [_apply_distribution_helper(child) for child in node.children])
    if len(node.children) == 1:
        child_node = node.children[0]
        if isinstance(child_node,
                      SetNode) and node.signature.arg_types[0][0] != '*':
            children = [
                FormulaNode(node.signature, [child])
                for child in child_node.children
            ]
            return SetNode(children)
    elif len(node.children) == 2:
        a_node, b_node = node.children
        if isinstance(
                a_node, SetNode
        ) and node.signature.arg_types[0][0] != '*' and isinstance(
                b_node, SetNode) and node.signature.arg_types[1][0] != '*':
            assert len(a_node.children) == len(b_node.children)
            children = [
                FormulaNode(node.signature,
                            [a_node.children[index], b_node.children[index]])
                for index in range(len(a_node.children))
            ]
            return SetNode(children)
        elif isinstance(
                a_node, SetNode
        ) and node.signature.arg_types[0][0] != '*' and isinstance(
                b_node, FormulaNode):
            children = [
                FormulaNode(node.signature, [child, b_node])
                for child in a_node.children
            ]
            return SetNode(children)
        elif isinstance(a_node, FormulaNode) and isinstance(
                b_node, SetNode) and node.signature.arg_types[1][0] != '*':
            children = [
                FormulaNode(node.signature, [a_node, child])
                for child in b_node.children
            ]
            return SetNode(children)

    return node
def evaluate(formula, assignment):
    if not isinstance(formula, Node):
        return formula
    if not formula.is_grounded(assignment.keys()):
        return None

    if isinstance(formula, SetNode):
        if issubtype(formula.head.return_type, 'boolean'):
            out = reduce(operator.__and__, (evaluate(child, assignment)
                                            for child in formula.children),
                         True)
            return out
        return formula

    if isinstance(formula.signature, VariableSignature):
        return assignment[formula.signature.id]
    elif is_number(formula.signature.id):
        return float(formula.signature.id)
    else:
        evaluated_args = []
        for arg in formula.children:
            if isinstance(arg, FormulaNode):
                evaluated_args.append(evaluate(arg, assignment))
            elif isinstance(arg, SetNode):
                evaluated_args.append(
                    SetNode([
                        evaluate(arg_arg, assignment)
                        for arg_arg in arg.children
                    ]))
            else:
                evaluated_args.append(arg)
        # FIXME : rather than try/catch, check type matching
        try:
            out = getattr(this, formula.signature.id)(*evaluated_args)
            return out
        except:
            return TruthValue(np.inf)
Ejemplo n.º 6
0
def _ground_variable(match_parse, variable, references={}):
    assert isinstance(variable, FormulaNode)
    assert isinstance(match_parse, MatchParse)
    return_type = variable.return_type
    graph_parse = match_parse.graph_parse
    core_parse = graph_parse.core_parse
    variable_signature = variable.signature

    if variable_signature.id in signatures:
        # pass What, Which, etc.
        return variable
    elif variable_signature.id in match_parse.graph_parse.core_parse.variable_assignment.keys(
    ):
        # pass point_0, point_1, etc.
        return variable
    elif isinstance(variable_signature,
                    VariableSignature) and variable_signature.is_ref():
        # @v_1, etc.
        return references[variable_signature.name]
    elif return_type == 'number':
        if is_number(variable_signature.name):
            return variable
        elif len(variable_signature.name) == 1:
            # x, y, z, etc. Need to redefine id (id shouldn't be tuple).
            return FormulaNode(
                VariableSignature(variable_signature.name, return_type), [])
        elif len(variable_signature.name
                 ) == 2 and variable_signature.name.isupper():
            new_leaf = FormulaNode(
                VariableSignature(variable.signature.id,
                                  "line",
                                  name=variable.signature.name), [])
            return FormulaNode(signatures['LengthOf'],
                               [_ground_variable(match_parse, new_leaf)])
    elif return_type == 'point':
        if len(variable_signature.name) == 1:
            return match_parse.match_dict[variable_signature.name][0]
        else:
            points = get_all_instances(graph_parse, 'point', True)
            return SetNode(points.values())
    elif return_type == 'line':
        if len(variable_signature.name
               ) == 1 and variable_signature.name in match_parse.match_dict:
            line = match_parse.match_dict[variable_signature.name][0]
            return line
        elif len(variable_signature.name
                 ) == 2 and variable_signature.name.isupper():
            label_a, label_b = variable_signature.name
            point_a = match_parse.match_dict[label_a][0]
            point_b = match_parse.match_dict[label_b][0]
            return FormulaNode(signatures['Line'], [point_a, point_b])
            """
        elif variable_signature.name == 'hypotenuse':
            def func(x):
                l, t = x
                formula = FormulaNode(signatures['IsHypotenuseOf'], (l,t))
                tv = core_parse.evaluate(formula)
                return tv.norm
            lines = get_all_instances(graph_parse, 'line', True).values()
            triangles = get_all_instances(graph_parse, 'triangle', True).values()
            line, triangle = min(itertools.product(lines, triangles), key=func)
            return line
            """

        else:
            lines = get_all_instances(graph_parse, 'line', True)
            return SetNode(lines.values())
    elif return_type == 'circle':
        if len(variable_signature.name) == 1:
            center_label = variable_signature.name
            center = match_parse.match_dict[center_label][0]
            center_idx = int(center.signature.name.split("_")[1])
            return graph_parse.circle_dict[center_idx][0]['variable']
            # radius = match_parse.graph_parse.core_parse.radius_variables[center_idx][0]
        elif variable_signature.name == 'circle':
            circles = get_all_instances(graph_parse, 'circle', True)
            return SetNode(circles.values())
        else:
            raise Exception()
    elif return_type == 'angle':
        # TODO :
        if len(variable_signature.name
               ) == 3 and variable_signature.name.isupper():
            label_a, label_b, label_c = variable_signature.name
            point_a = match_parse.match_dict[label_a][0]
            point_b = match_parse.match_dict[label_b][0]
            point_c = match_parse.match_dict[label_c][0]
            out = FormulaNode(signatures['Angle'], [point_a, point_b, point_c])
            measure = evaluate(FormulaNode(signatures['MeasureOf'], [out]),
                               core_parse.variable_assignment)
            if measure > np.pi:
                out = FormulaNode(signatures['Angle'],
                                  [point_c, point_b, point_a])
            return out
        elif len(variable_signature.name
                 ) == 1 and variable_signature.name.isupper():
            angles = get_all_instances(graph_parse, 'angle', True)
            p = match_parse.match_dict[variable_signature.name][0]
            for formula in angles.values():
                if formula.children[1].signature == p.signature:
                    measure = evaluate(
                        FormulaNode(signatures['MeasureOf'], [formula]),
                        core_parse.variable_assignment)
                    if measure > np.pi:
                        continue
                    return formula

        elif len(variable_signature.name
                 ) == 1 and variable_signature.name.islower():
            return match_parse.match_dict[variable_signature.name][0]
    elif return_type == 'arc':
        if len(variable_signature.name
               ) == 2 and variable_signature.name.isupper():
            point_keys = [
                match_parse.point_key_dict[label]
                for label in variable_signature.name
            ]
            test_arc = get_instances(graph_parse, 'arc', False,
                                     *point_keys).values()[0]
            if MeasureOf(test_arc) > np.pi:
                point_keys = [point_keys[1], point_keys[0]]
            arc = get_instances(graph_parse, 'arc', True,
                                *point_keys).values()[0]
            return arc
        else:
            arcs = get_all_instances(graph_parse, 'arc', True)
            return SetNode(arcs.values())

    elif return_type == 'triangle':
        if variable_signature.name.isupper() and len(
                variable_signature.name) == 3:
            point_keys = [
                match_parse.point_key_dict[label]
                for label in variable_signature.name
            ]
            triangles = get_instances(graph_parse, 'triangle', True,
                                      *point_keys)
            return triangles.values()[0]
        else:
            triangles = get_all_instances(graph_parse, 'triangle', True)
            return SetNode(triangles.values())
    elif return_type == 'quad':
        if variable_signature.name.isupper() and len(
                variable_signature.name) == 4:
            point_keys = [
                match_parse.point_key_dict[label]
                for label in variable_signature.name
            ]
            quads = get_instances(graph_parse, 'quad', True, *point_keys)
            return quads.values()[0]
        else:
            quads = get_all_instances(graph_parse, 'quad', True)
            return SetNode(quads.values())
    elif return_type == 'hexagon':
        if variable_signature.name.isupper() and len(
                variable_signature.name) == 6:
            point_keys = [
                match_parse.point_key_dict[label]
                for label in variable_signature.name
            ]
            hexagons = get_instances(graph_parse, 'hexagon', True, *point_keys)
            return hexagons.values()[0]
        else:
            quads = get_all_instances(graph_parse, 'hexagon', True)
            return SetNode(quads.values())
    elif return_type == 'polygon':
        if variable_signature.name.isupper():
            point_keys = [
                match_parse.point_key_dict[label]
                for label in variable_signature.name
            ]
            polygons = get_instances(graph_parse, 'polygon', True, *point_keys)
            return polygons.values()[0]
        else:
            polygons = get_all_instances(graph_parse, 'polygon', True)
            return SetNode(polygons.values())
    elif return_type == 'twod':
        circles = get_all_instances(graph_parse, 'circle', True)
        polygons = get_all_instances(graph_parse, 'polygon', True)
        return SetNode(polygons.values() + circles.values())
    elif return_type == 'oned':
        lines = get_all_instances(graph_parse, 'line', True)
        arcs = get_all_instances(graph_parse, 'arc', True)
        return SetNode(lines.values() + arcs.values())

    #logging.warning("failed to ground variable: %r" % variable)
    raise Exception()