Ejemplo n.º 1
0
def eq_comm(u, v, eq=None):
    """ Goal for commutative equality

    >>> from kanren import run, var, fact
    >>> from kanren.assoccomm import eq_comm as eq
    >>> from kanren.assoccomm import commutative, associative

    >>> fact(commutative, 'add')    # declare that 'add' is commutative
    >>> fact(associative, 'add')    # declare that 'add' is associative

    >>> x = var()
    >>> run(0, x, eq(('add', 1, 2, 3), ('add', 2, x, 1)))
    (3,)
    """
    eq = eq or eq_comm
    vtail = var()
    if isvar(u) and isvar(v):
        return (core.eq, u, v)
    uop, uargs = op_args(u)
    vop, vargs = op_args(v)
    if not uop and not vop:
        return (core.eq, u, v)
    if vop and not uop:
        uop, uargs = vop, vargs
        v, u = u, v
    return (conde, ((core.eq, u, v), ),
            ((commutative, uop), (buildo, uop, vtail, v), (permuteq, uargs,
                                                           vtail, eq)))
Ejemplo n.º 2
0
def test_nullo_itero():

    x, y, z = var(), var(), var()
    q_lv, a_lv = var(), var()

    assert run(0, q_lv, conso(1, q_lv, [1]), nullo(q_lv))
    assert run(0, q_lv, nullo(q_lv), conso(1, q_lv, [1]))

    assert not run(0, q_lv, nullo(q_lv, [], ()))
    assert run(0, [a_lv, q_lv], nullo(q_lv, a_lv,
                                      default_ConsNull=tuple)) == ([(), ()], )
    assert run(0, [a_lv, q_lv], nullo(a_lv, [], q_lv)) == ([[], []], )

    assert ([], ) == run(0, q_lv, nullo(q_lv, []))
    assert ([], ) == run(0, q_lv, nullo([], q_lv))
    assert (None, ) == run(0, q_lv, nullo(None, q_lv))
    assert (tuple(), ) == run(0, q_lv, nullo(tuple(), q_lv))
    assert (q_lv, ) == run(0, q_lv, nullo(tuple(), tuple()))
    assert ([], ) == run(0, q_lv, nullo(var(), q_lv))
    assert ([], ) == run(0, q_lv, nullo(q_lv, var()))
    assert ([], ) == run(0, q_lv, nullo(q_lv, q_lv))

    assert isvar(run(0, y, nullo([]))[0])
    assert isvar(run(0, y, nullo(None))[0])
    assert run(0, y, nullo(y))[0] == []
    assert run(0, y, conso(var(), y, [1]), nullo(y))[0] == []
    assert run(0, y, conso(var(), y, (1, )), nullo(y))[0] == ()

    assert run(1, y, conso(1, x, y), itero(y))[0] == [1]
    assert run(1, y, conso(1, x, y), conso(2, z, x), itero(y))[0] == [1, 2]

    # Make sure that the remaining results end in logic variables
    res_2 = run(2, y, conso(1, x, y), conso(2, z, x), itero(y))[1]
    assert res_2[:2] == [1, 2]
    assert isvar(res_2[-1])
Ejemplo n.º 3
0
def lvar_ignore_ne(x, y):
    if (isvar(x)
            and isvar(y)) or (isinstance(x, type) and isinstance(y, type)
                              and issubclass(x, Var) and issubclass(y, Var)):
        return False
    else:
        return ne(x, y)
Ejemplo n.º 4
0
    def goal(substitution):
        newx, newy = reify((x, y), substitution)

        def apply_constrain(oldvar, newvar):
            if hasrange(oldvar):
                newvar = RangedVar.new_from_intersection(oldvar, newvar)
                if newvar:
                    yield temp_assoc(substitution, oldvar, newvar)
            else:
                yield temp_assoc(substitution, oldvar, newvar)

        if isvar(newx):
            if isvar(newy):
                raise EarlyGoalError('two vars in comparison')
            elif isinstance(newy, Number):
                oldvar = newx
                newvar = RangedVar(RealRange([(newy, np.inf)]))
                yield from apply_constrain(oldvar, newvar)
            else:
                raise EarlyGoalError('Invalid constant type')
        elif isinstance(newx, Number):
            if isvar(newy):
                oldvar = newy
                newvar = RangedVar(RealRange([(-np.inf, newx)]))
                yield from apply_constrain(oldvar, newvar)
            elif isinstance(newy, Number):
                if newx > newy:
                    yield substitution
            else:
                raise EarlyGoalError('Invalid constant type')
        else:
            raise EarlyGoalError('Invalid constant type')
Ejemplo n.º 5
0
def _(obj, printer):

    try:
        shape_str = str(obj.shape.as_list())
    except (ValueError, AttributeError):
        shape_str = "Unknown"

    prefix = f'Tensor({getattr(obj.op, "type", obj.op)}):{obj.value_index},\tdtype={getattr(obj.dtype, "name", obj.dtype)},\tshape={shape_str},\t"{obj.name}"'
    _tf_dprint(prefix, printer)

    if isvar(obj.op):
        return
    elif isvar(obj.op.inputs):
        with printer.indented("|  "):
            _tf_dprint(f"{obj.op.inputs}", printer)
    elif len(obj.op.inputs) > 0:
        with printer.indented("|  "):
            if obj not in printer.printed_subgraphs:
                printer.printed_subgraphs.add(obj)
                _tf_dprint(obj.op, printer)
            else:
                _tf_dprint("...", printer)
    elif obj.op.type == "Const":
        with printer.indented("|  "):
            if isinstance(obj, tf.Tensor):
                numpy_val = obj.eval(session=tf.compat.v1.Session(graph=obj.graph))
            elif isvar(obj.op.node_def):
                _tf_dprint(f"{obj.op.node_def}", printer)
                return
            else:
                numpy_val = obj.op.node_def.attr["value"]

            _tf_dprint(
                np.array2string(numpy_val, threshold=20, prefix=printer.indentation), printer
            )
Ejemplo n.º 6
0
def eq_comm(u, v, eq=None):
    """ Goal for commutative equality

    >>> from kanren import run, var, fact
    >>> from kanren.assoccomm import eq_comm as eq
    >>> from kanren.assoccomm import commutative, associative

    >>> fact(commutative, 'add')    # declare that 'add' is commutative
    >>> fact(associative, 'add')    # declare that 'add' is associative

    >>> x = var()
    >>> run(0, x, eq(('add', 1, 2, 3), ('add', 2, x, 1)))
    (3,)
    """
    eq = eq or eq_comm
    vtail = var()
    if isvar(u) and isvar(v):
        return (core.eq, u, v)
    uop, uargs = op_args(u)
    vop, vargs = op_args(v)
    if not uop and not vop:
        return (core.eq, u, v)
    if vop and not uop:
        uop, uargs = vop, vargs
        v, u = u, v
    return (conde, ((core.eq, u, v), ),
            ((commutative, uop), (buildo, uop, vtail, v),
             (permuteq, uargs, vtail, eq)))
Ejemplo n.º 7
0
def test_meta_dtype_inference():

    one_int_mt = mt(1)
    res = mt.add.output_meta_types({'x': one_int_mt})
    assert res[0][0] == TFlowMetaTensor
    assert res[0][1] == tf.int32

    one_flt_mt = mt(1.0)
    res = mt.add.output_meta_types({'y': one_flt_mt})
    assert res[0][0] == TFlowMetaTensor
    assert res[0][1] == tf.float32

    res = mt.add.output_meta_types({'T': tf.int32})
    assert res[0][0] == TFlowMetaTensor
    assert res[0][1] == tf.int32

    add_mt = TFlowMetaOperator(mt.add.op_def,
                               TFlowMetaNodeDef('Add', 'my_add', {'T': 1}))
    res = add_mt.output_meta_types()
    assert res[0][0] == TFlowMetaTensor
    assert res[0][1] == tf.float32

    with pytest.raises(AssertionError):
        # These integer types conflict with the NodeDef type in our operator,
        # `add_mt`.
        add_mt(1, 2)

    res = mt.cast.output_meta_types({'dtype': 'blah'})
    assert res[0][0] == TFlowMetaTensor
    assert isvar(res[0][1])

    res = mt.placeholder.output_meta_types({'dtype': 'blah'})
    assert isvar(res[0][1])
Ejemplo n.º 8
0
    def reify(self):
        if self.obj and not isinstance(self.obj, Var):
            return self.obj

        if isvar(self.inputs):
            return self

        op_inputs, op_inputs_unreified = meta_reify_iter(self.inputs)

        node_attr = getattr(self.node_def, "attr", None)

        if node_attr is None or isvar(node_attr):
            return self

        operator = TFlowMetaOperator(self.op_def, self.node_def)

        op_attrs, op_attrs_unreified = meta_reify_iter(
            # Only use NodeDef attrs that appear in the OpDef's call signature.
            # Other NodeDef attrs, like dtype and shape, can be computed.
            {
                k: v
                for k, v in node_attr.items()
                if k in operator._apply_func_sig.parameters
            })

        if not (op_inputs_unreified or op_attrs_unreified or isvar(self.name)):
            #
            # An operation with this name might already exist in the graph
            #
            try:
                existing_op = ops.get_default_graph().get_operation_by_name(
                    self.name)
            except KeyError:
                #
                # There is no such `Operation`, so we attempt to create it
                #
                apply_arguments = operator.input_args(*op_inputs,
                                                      name=self.name,
                                                      **op_attrs)
                tf_out = operator._apply_func(**apply_arguments)
                op_tf = tf_out.op
            else:
                #
                # An `Operation` with this name exists, let's make sure it's
                # equivalent to this meta `Operation`
                #
                if self != mt(existing_op):
                    raise MetaReificationError(
                        f"An Operation with the name {self.name}"
                        " already exists in the graph and is not"
                        " equal to this meta object.")
                op_tf = existing_op

            assert op_tf is not None
            self._obj = op_tf
            return self.obj

        return self
Ejemplo n.º 9
0
        def seq_apply_anyo_sub_goal(s):

            nonlocal i_any, null_type

            l_in_rf, l_out_rf = reify((l_in, l_out), s)

            i_car, i_cdr = var(), var()
            o_car, o_cdr = var(), var()

            conde_branches = []

            if i_any or (isvar(l_in_rf) and isvar(l_out_rf)):
                # Consider terminating the sequences when we've had at least
                # one successful goal or when both sequences are logic variables.
                conde_branches.append([eq(l_in_rf, null_type), eq(l_in_rf, l_out_rf)])

            # Extract the CAR and CDR of each argument sequence; this is how we
            # iterate through elements of the two sequences.
            cons_parts_branch = [
                goaleval(conso(i_car, i_cdr, l_in_rf)),
                goaleval(conso(o_car, o_cdr, l_out_rf)),
            ]

            conde_branches.append(cons_parts_branch)

            conde_relation_branches = []

            relation_branch = None

            if not skip_cars:
                relation_branch = [
                    # This case tries the relation continues on.
                    relation(i_car, o_car),
                    # In this conde clause, we can tell future calls to
                    # seq_apply_anyo that we've had at least one successful
                    # application of the relation (otherwise, this clause
                    # would fail due to the above goal).
                    _seq_apply_anyo(relation, i_cdr, o_cdr, True, null_type),
                ]

                conde_relation_branches.append(relation_branch)

            base_branch = [
                # This is the "base" case; it is used when, for example,
                # the given relation isn't satisfied.
                eq(i_car, o_car),
                _seq_apply_anyo(relation, i_cdr, o_cdr, i_any, null_type),
            ]

            conde_relation_branches.append(base_branch)

            cons_parts_branch.append(conde(*conde_relation_branches))

            g = conde(*conde_branches)
            g = goaleval(g)

            yield from g(s)
Ejemplo n.º 10
0
def buildo(op, args, obj):
    if not isvar(obj):
        if not isvar(args):
            args = etuplize(args, shallow=True)
        oop, oargs = operator(obj), arguments(obj)
        return lallgreedy(eq(op, oop), eq(args, oargs))
    elif isvar(args) or isvar(op):
        return conso(op, args, obj)
    else:
        return eq(obj, term(op, args))
Ejemplo n.º 11
0
    def base_arguments(self):
        # TODO: In keeping with our desire to return logic variables in cases
        # where params aren't given/inferred, we could return something like
        # `cons(var(), var())` here (although that wouldn't be necessarily
        # imply that the result is a proper list/tuple).
        if isvar(self.op) or (not isvar(self.op.inputs)
                              and len(self.op.inputs) == 0):
            raise NotImplementedError(f"{self} does not have base arguments.")

        return self.op.inputs
Ejemplo n.º 12
0
    def base_operator(self):
        if getattr(self, "_operator", None):
            return self._operator

        if isvar(self.op) or (not isvar(self.op.inputs)
                              and len(self.op.inputs) == 0):
            raise NotImplementedError(f"{self} does not have a base_operator.")

        self._operator = TFlowMetaOperator(self.op.op_def, self.op.node_def)

        return self._operator
Ejemplo n.º 13
0
def test_nullo_itero():
    assert isvar(run(0, y, nullo([]))[0])
    assert isvar(run(0, y, nullo(None))[0])
    assert run(0, y, nullo(y))[0] is None
    assert run(0, y, (conso, var(), y, [1]), nullo(y))[0] == []
    assert run(0, y, (conso, var(), y, (1, )), nullo(y))[0] == ()

    assert run(1, y, conso(1, x, y), itero(y))[0] == [1]
    assert run(1, y, conso(1, x, y), conso(2, z, x), itero(y))[0] == [1, 2]

    # Make sure that the remaining results end in logic variables
    res_2 = run(2, y, conso(1, x, y), conso(2, z, x), itero(y))[1]
    assert res_2[:2] == [1, 2]
    assert isvar(res_2[-1])
Ejemplo n.º 14
0
def test_nullo_itero():
    assert isvar(run(0, y, nullo([]))[0])
    assert isvar(run(0, y, nullo(None))[0])
    assert run(0, y, nullo(y))[0] is None
    assert run(0, y, (conso, var(), y, [1]), nullo(y))[0] == []
    assert run(0, y, (conso, var(), y, (1,)), nullo(y))[0] == ()

    assert run(1, y, conso(1, x, y), itero(y))[0] == [1]
    assert run(1, y, conso(1, x, y), conso(2, z, x), itero(y))[0] == [1, 2]

    # Make sure that the remaining results end in logic variables
    res_2 = run(2, y, conso(1, x, y), conso(2, z, x), itero(y))[1]
    assert res_2[:2] == [1, 2]
    assert isvar(res_2[-1])
Ejemplo n.º 15
0
    def __init__(self, op, inputs, outputs=None, obj=None):
        self.op = metatize(op)

        if not isvar(inputs):
            self.inputs = tuple(metatize(i) for i in inputs)
        else:
            self.inputs = inputs

        if outputs is not None and not isvar(outputs):
            self._outputs = tuple(metatize(o) for o in outputs)
        else:
            self._outputs = outputs

        super().__init__(obj=obj)
Ejemplo n.º 16
0
def eq_assoccomm(u, v):
    """ Associative/Commutative eq

    Works like logic.core.eq but supports associative/commutative expr trees

    tree-format:  (op, *args)
    example:      (add, 1, 2, 3)

    State that operations are associative or commutative with relations

    >>> from kanren.assoccomm import eq_assoccomm as eq
    >>> from kanren.assoccomm import commutative, associative
    >>> from kanren import fact, run, var

    >>> fact(commutative, 'add')    # declare that 'add' is commutative
    >>> fact(associative, 'add')    # declare that 'add' is associative

    >>> x = var()
    >>> e1 = ('add', 1, 2, 3)
    >>> e2 = ('add', 1, x)
    >>> run(0, x, eq(e1, e2))
    (('add', 2, 3), ('add', 3, 2))
    """
    uop, uargs = op_args(u)
    vop, vargs = op_args(v)

    if uop and not vop and not isvar(v):
        return fail
    if vop and not uop and not isvar(u):
        return fail
    if uop and vop and uop != vop:
        return fail
    if uop and not (uop, ) in associative.facts:
        return (eq, u, v)
    if vop and not (vop, ) in associative.facts:
        return (eq, u, v)

    if uop and vop:
        u, v = (u, v) if len(uargs) >= len(vargs) else (v, u)
        n = min(map(len, (uargs, vargs)))  # length of shorter tail
    else:
        n = None
    if vop and not uop:
        u, v = v, u
    w = var()
    # TODO: Is greedy correct?
    return (lallgreedy, (eq_assoc, u, w, eq_assoccomm, n), (eq_comm, v, w,
                                                            eq_assoccomm))
Ejemplo n.º 17
0
def eq_assoccomm(u, v):
    """ Associative/Commutative eq

    Works like logic.core.eq but supports associative/commutative expr trees

    tree-format:  (op, *args)
    example:      (add, 1, 2, 3)

    State that operations are associative or commutative with relations

    >>> from kanren.assoccomm import eq_assoccomm as eq
    >>> from kanren.assoccomm import commutative, associative
    >>> from kanren import fact, run, var

    >>> fact(commutative, 'add')    # declare that 'add' is commutative
    >>> fact(associative, 'add')    # declare that 'add' is associative

    >>> x = var()
    >>> e1 = ('add', 1, 2, 3)
    >>> e2 = ('add', 1, x)
    >>> run(0, x, eq(e1, e2))
    (('add', 2, 3), ('add', 3, 2))
    """
    uop, uargs = op_args(u)
    vop, vargs = op_args(v)

    if uop and not vop and not isvar(v):
        return fail
    if vop and not uop and not isvar(u):
        return fail
    if uop and vop and uop != vop:
        return fail
    if uop and not (uop, ) in associative.facts:
        return (eq, u, v)
    if vop and not (vop, ) in associative.facts:
        return (eq, u, v)

    if uop and vop:
        u, v = (u, v) if len(uargs) >= len(vargs) else (v, u)
        n = min(map(len, (uargs, vargs)))  # length of shorter tail
    else:
        n = None
    if vop and not uop:
        u, v = v, u
    w = var()
    # TODO: Is greedy correct?
    return (lallgreedy, (eq_assoc, u, w, eq_assoccomm, n),
            (eq_comm, v, w, eq_assoccomm))
Ejemplo n.º 18
0
    def op_args_to_operation_inputs(self, apply_arguments):
        """Map an `OpDef`'s "apply function" arguments to `Operation` inputs and a meta `NodeDef`."""

        if isvar(self.op_def):
            return None

        op_def_tf = self.op_def.obj

        op_inputs = tuple(
            apply_arguments.get(i.name) for i in op_def_tf.input_arg
            if i.name in apply_arguments)

        # TODO: Include inferred attr values (e.g. dtypes).
        if "node_attrs" not in meta._lvar_defaults_enabled:
            node_attr = {
                a.name: apply_arguments.get(a.name, a)
                for a in op_def_tf.attr
            }
        else:
            node_attr = var()

        if "names" not in meta._lvar_defaults_enabled:
            op_name = apply_arguments.get("name",
                                          op_def_tf.name) or op_def_tf.name
        else:
            op_name = var()

        node_def = TFlowMetaNodeDef(op_def_tf.name, op_name, node_attr)

        return op_inputs, node_def
Ejemplo n.º 19
0
def meta_reify_iter(rands):
    """Recursively reify an iterable object and return a boolean indicating the presence of un-reifiable objects, if any."""
    any_unreified = False
    reified_rands = []

    _rands = rands
    if isinstance(_rands, Mapping):
        _rands = _rands.items()

    for s in _rands:
        if isinstance(s, MetaSymbol):
            rrand = s.reify()
            reified_rands.append(rrand)
            any_unreified |= isinstance(rrand, MetaSymbol)
            any_unreified |= isvar(rrand)
        elif MetaSymbol.is_meta(s):
            reified_rands.append(s)
            any_unreified |= True
        elif isinstance(s, (list, tuple)):
            _reified_rands, _any_unreified = meta_reify_iter(s)
            reified_rands.append(type(s)(_reified_rands))
            any_unreified |= _any_unreified
        else:
            reified_rands.append(s)

    return type(rands)(reified_rands), any_unreified
Ejemplo n.º 20
0
def evalo(program: ast.AST, value: Var, replace_var: str = None):
    replace_var = replace_var or DEFAULT_REPLACE_VAR
    if value.token != replace_var:
        raise RuntimeError("Value {} should have token {}".format(
            value, replace_var))

    program = strip_ast(program)
    program = replace_ast_name_with_lvar(program, replace_var=replace_var)

    goals, env = eval_programo(program, [], value)
    res = run(1, value, goals)

    r = res[0]
    logger.info("Final result: {}".format(ast_dump_if_possible(res)))
    if isvar(r):
        logger.info("No results found for {}: {}".format(value, r))
        return r
    logger.info("Found {} to be {}".format(ast_dump_if_possible(value),
                                           ast_dump_if_possible(r)))
    # TODO: This only works on the last assign
    if isinstance(r, ast.Name):
        evaluated_value = literal_lookup(r.id, env)
        logger.info("Found evaluated value {}".format(
            ast_dump_if_possible(evaluated_value)))
        return evaluated_value
Ejemplo n.º 21
0
 def as_tuple(self):
     tail = self.tail
     if isinstance(tail, LCons):
         tail = self.tail.as_tuple()
     elif isvar(tail):
         raise EarlyGoalError()
     return (self.head, ) + tail
Ejemplo n.º 22
0
    def __call__(self, *args):
        """ Returns an evaluated (callable) goal, which returns a list of
        substitutions which match args against a fact in the knowledge base.

        *args: the goal to evaluate. This consists of vars and values to
               match facts against.
        """
        def goal(substitution):
            args2 = reify(args, substitution)
            subsets = [
                self.index[key] for key in enumerate(args) if key in self.index
            ]
            if subsets:  # we are able to reduce the pool early
                facts = intersection(*sorted(subsets, key=len))
            else:
                facts = self.facts

            for fact in facts:
                unified = unify(fact, args2, substitution)
                if unified != False:
                    yield merge(unified, substitution)

        for x in args:
            if isvar(x):
                return goal

        return self.op(*args)
Ejemplo n.º 23
0
 def as_tuple(self):
     tail = self.tail
     if isinstance(tail, LCons):
         tail = self.tail.as_tuple()
     elif isvar(tail):
         raise EarlyGoalError()
     return (self.head, ) + tail
Ejemplo n.º 24
0
def test_meta_operation():

    t1_tf = tf.convert_to_tensor([[1, 2, 3], [4, 5, 6]])
    t2_tf = tf.convert_to_tensor([[7, 8, 9], [10, 11, 12]])
    test_out_tf = tf.concat([t1_tf, t2_tf], 0)

    # Just make sure it doesn't raise and exception
    mt.ConcatV2.op_def.validate_objs()
    assert mt.ConcatV2.op_def.reify() == test_out_tf.op.op_def

    # TODO: Without explicit conversion, each element within these arrays gets
    # converted to a `Tensor` by `metatize`.  That doesn't seem very
    # reasonable.  Likewise, the `0` gets converted, but it probably shouldn't be.
    test_op = TFlowMetaOp(mt.Concat.op_def, var(), [[t1_tf, t2_tf], 0])

    assert isvar(test_op.name)

    # Make sure we converted lists to tuples
    assert isinstance(test_op.inputs, tuple)
    assert isinstance(test_op.inputs[0], tuple)

    test_op = TFlowMetaOp(
        mt.Concat.op_def,
        var(),
        [[t1_tf, t2_tf], 0],
        # This tensor isn't actually consistent with the
        # OpDef we're using (i.e. Concat != ConcatV2)!
        outputs=[test_out_tf])

    # NodeDef is a logic variable, so this shouldn't actually reify.
    assert MetaSymbol.is_meta(test_op.reify())
    assert isinstance(test_op.outputs, tuple)
    assert MetaSymbol.is_meta(test_op.outputs[0])
Ejemplo n.º 25
0
Archivo: goals.py Proyecto: logpy/logpy
def permuteq(a, b, eq2=eq):
    """ Equality under permutation

    For example (1, 2, 2) equates to (2, 1, 2) under permutation
    >>> from kanren import var, run, permuteq
    >>> x = var()
    >>> run(0, x, permuteq(x, (1, 2)))
    ((1, 2), (2, 1))

    >>> run(0, x, permuteq((2, 1, x), (2, 1, 2)))
    (2,)
    """
    if isinstance(a, tuple) and isinstance(b, tuple):
        if len(a) != len(b):
            return fail
        elif collections.Counter(a) == collections.Counter(b):
            return success
        else:
            c, d = list(a), list(b)
            for x in list(c):
                # TODO: This is quadratic in the number items in the sequence.
                # Need something like a multiset. Maybe use
                # collections.Counter?
                try:
                    d.remove(x)
                    c.remove(x)
                except ValueError:
                    pass
            c, d = tuple(c), tuple(d)
            if len(c) == 1:
                return (eq2, c[0], d[0])
            return condeseq(
                ((eq2, x, d[0]), (permuteq, c[0:i] + c[i + 1:], d[1:], eq2))
                for i, x in enumerate(c)
            )

    if isvar(a) and isvar(b):
        raise EarlyGoalError()

    if isvar(a) or isvar(b):
        if isinstance(b, tuple):
            c, d = a, b
        elif isinstance(a, tuple):
            c, d = b, a

        return (condeseq, ([eq(c, perm)]
                           for perm in unique(permutations(d, len(d)))))
Ejemplo n.º 26
0
def permuteq(a, b, eq2=eq):
    """ Equality under permutation

    For example (1, 2, 2) equates to (2, 1, 2) under permutation
    >>> from mykanren import var, run, permuteq
    >>> x = var()
    >>> run(0, x, permuteq(x, (1, 2)))
    ((1, 2), (2, 1))

    >>> run(0, x, permuteq((2, 1, x), (2, 1, 2)))
    (2,)
    """
    if isinstance(a, tuple) and isinstance(b, tuple):
        if len(a) != len(b):
            return fail
        elif collections.Counter(a) == collections.Counter(b):
            return success
        else:
            c, d = list(a), list(b)
            for x in list(c):
                # TODO: This is quadratic in the number items in the sequence.
                # Need something like a multiset. Maybe use
                # collections.Counter?
                try:
                    d.remove(x)
                    c.remove(x)
                except ValueError:
                    pass
            c, d = tuple(c), tuple(d)
            if len(c) == 1:
                return (eq2, c[0], d[0])
            return condeseq(
                ((eq2, x, d[0]), (permuteq, c[0:i] + c[i + 1:], d[1:], eq2))
                for i, x in enumerate(c)
            )

    if isvar(a) and isvar(b):
        raise EarlyGoalError()

    if isvar(a) or isvar(b):
        if isinstance(b, tuple):
            c, d = a, b
        elif isinstance(a, tuple):
            c, d = b, a

        return (condeseq, ([eq(c, perm)]
                           for perm in unique(permutations(d, len(d)))))
Ejemplo n.º 27
0
def op_args(x):
    """ Break apart x into an operation and tuple of args """
    if isvar(x):
        return None, None
    try:
        return operator(x), arguments(x)
    except NotImplementedError:
        return None, None
Ejemplo n.º 28
0
def op_args(x):
    """ Break apart x into an operation and tuple of args """
    if isvar(x):
        return None, None
    try:
        return operator(x), arguments(x)
    except NotImplementedError:
        return None, None
Ejemplo n.º 29
0
 def funco(inputs, out):
     if isvar(inputs):
         raise EarlyGoalError()
     else:
         if isinstance(inputs, (tuple, list)):
             return (eq, func(*inputs), out)
         else:
             return (eq, func(inputs), out)
Ejemplo n.º 30
0
def test_eq_length():
    q_lv = var()

    res = run(0, q_lv, eq_length([1, 2, 3], q_lv))
    assert len(res) == 1 and len(res[0]) == 3 and all(isvar(q) for q in res[0])

    res = run(0, q_lv, eq_length(q_lv, [1, 2, 3]))
    assert len(res) == 1 and len(res[0]) == 3 and all(isvar(q) for q in res[0])

    res = run(0, q_lv, eq_length(cons(1, q_lv), [1, 2, 3]))
    assert len(res) == 1 and len(res[0]) == 2 and all(isvar(q) for q in res[0])

    v_lv = var()
    res = run(3, (q_lv, v_lv), eq_length(q_lv, v_lv, default_ConsNull=tuple))
    assert len(res) == 3 and all(
        isinstance(a, tuple) and len(a) == len(b) and
        (len(a) == 0 or a != b) and all(isvar(r) for r in a) for a, b in res)
Ejemplo n.º 31
0
def ground_order_key(S, x):
    if isvar(x):
        return 2
    elif isground(x, S):
        return -1
    elif issubclass(type(x), ConsPair):
        return 1
    else:
        return 0
Ejemplo n.º 32
0
    def frozen_attr(self):
        if getattr(self, "_frozen_attr", None) is not None:
            return self._frozen_attr

        if isvar(self.attr):
            self._frozen_attr = self.attr
        else:
            self._frozen_attr = frozenset(self.attr.items())
        return self._frozen_attr
Ejemplo n.º 33
0
 def __init__(self, dims, obj=None):
     super().__init__(obj=obj)
     self.dims = dims
     if self.dims is not None and not isvar(self.dims):
         # TODO: Just like the comment in `TFlowMetaTensor.inputs`,
         # `self.dims` should be something like `cons(var(), ...)` and not a
         # straight logic variable.
         self.dims = tuple(
             tensor_shape.as_dimension(d).value for d in self.dims)
Ejemplo n.º 34
0
def test_map_anyo_misc():
    q_lv = var("q")

    res = run(0, q_lv, map_anyo(eq, [1, 2, 3], [1, 2, 3]))
    # TODO: Remove duplicate results
    assert len(res) == 7
    res = run(0, q_lv, map_anyo(eq, [1, 2, 3], [1, 3, 3]))
    assert len(res) == 0

    def one_to_threeo(x, y):
        return conde([eq(x, 1), eq(y, 3)])

    res = run(0, q_lv, map_anyo(one_to_threeo, [1, 2, 4, 1, 4, 1, 1], q_lv))

    assert res[0] == [3, 2, 4, 3, 4, 3, 3]

    assert (len(
        run(4, q_lv, map_anyo(math_reduceo, [etuple(mul, 2, var("x"))],
                              q_lv))) == 0)

    test_res = run(4, q_lv, map_anyo(math_reduceo, [etuple(add, 2, 2), 1],
                                     q_lv))
    assert test_res == ([etuple(mul, 2, 2), 1], )

    test_res = run(4, q_lv, map_anyo(math_reduceo, [1, etuple(add, 2, 2)],
                                     q_lv))
    assert test_res == ([1, etuple(mul, 2, 2)], )

    test_res = run(4, q_lv, map_anyo(math_reduceo, q_lv, var("z")))
    assert all(isinstance(r, list) for r in test_res)

    test_res = run(4, q_lv, map_anyo(math_reduceo, q_lv, var("z"), tuple))
    assert all(isinstance(r, tuple) for r in test_res)

    x, y, z = var(), var(), var()

    def test_bin(a, b):
        return conde([eq(a, 1), eq(b, 2)])

    res = run(10, (x, y), map_anyo(test_bin, x, y, null_type=tuple))
    exp_res_form = (
        ((1, ), (2, )),
        ((x, 1), (x, 2)),
        ((1, 1), (2, 2)),
        ((x, y, 1), (x, y, 2)),
        ((1, x), (2, x)),
        ((x, 1, 1), (x, 2, 2)),
        ((1, 1, 1), (2, 2, 2)),
        ((x, y, z, 1), (x, y, z, 2)),
        ((1, x, 1), (2, x, 2)),
        ((x, 1, y), (x, 2, y)),
    )

    for a, b in zip(res, exp_res_form):
        s = unify(a, b)
        assert s is not False
        assert all(isvar(i) for i in reify((x, y, z), s))
Ejemplo n.º 35
0
        def infer_output_types(o):
            """Get dtypes for specific outputs using known dtype info and API inputs."""
            # Get the explicit type from a `NodeDef` attribute.
            type_name = o.type_attr

            # Existing dtype value
            dtype = type_map[type_name]
            # New value
            _dtype = None

            # The information could be in the `NodeDef`
            if isinstance(getattr(self.node_def, "attr", None), dict):
                _dtype = self.node_def.attr.get(type_name)

            # It could also be in the inputs (i.e. when called via the API
            # route)
            # TODO: If it's in the inputs, we should just create the
            # corresponding `NodeDef`.
            if inputs and type_name in inputs:
                _dtype = inputs.get(type_name)

            if _dtype is None:
                _dtype = var()

            if not isvar(_dtype):
                try:
                    _dtype = tf.dtypes.as_dtype(_dtype).base_dtype
                except TypeError:
                    _dtype = var()

            # Make sure dtypes derived from `NodeDef` info and API inputs are
            # consistent.
            if dtype is None or isvar(dtype):
                # Newly inferred dtype is at least as informative as the
                # current one
                dtype = _dtype
                type_map[type_name] = dtype
            elif _dtype is None or isvar(_dtype):
                # Newly inferred dtype is less informative
                pass
            else:
                assert dtype == _dtype

            return (TFlowMetaTensor, dtype)
Ejemplo n.º 36
0
def test_metatize():
    vec_tt = tt.vector('vec')
    vec_m = metatize(vec_tt)
    assert vec_m.base == type(vec_tt)

    test_list = [1, 2, 3]
    metatize_test_list = metatize(test_list)
    assert isinstance(metatize_test_list, list)
    assert all(isinstance(m, MetaSymbol) for m in metatize_test_list)

    test_iter = iter([1, 2, 3])
    metatize_test_iter = metatize(test_iter)
    assert isinstance(metatize_test_iter, Iterator)
    assert all(isinstance(m, MetaSymbol) for m in metatize_test_iter)

    test_out = metatize(var())
    assert isvar(test_out)

    with variables(vec_tt):
        test_out = metatize(vec_tt)
        assert test_out == vec_tt
        assert isvar(test_out)

    test_out = metatize(np.r_[1, 2, 3])
    assert isinstance(test_out, MetaSymbol)

    class TestClass(object):
        pass

    with pytest.raises(Exception):
        metatize(TestClass())

    class TestOp(tt.gof.Op):
        pass

    test_out = metatize(TestOp)
    assert issubclass(test_out, MetaOp)

    test_op_tt = TestOp()
    test_obj = test_out(obj=test_op_tt)
    assert isinstance(test_obj, MetaSymbol)
    assert test_obj.obj == test_op_tt
    assert test_obj.base == TestOp
Ejemplo n.º 37
0
 def funco(inputs, out):
     if isvar(inputs):
         raise EarlyGoalError()
     else:
         if isinstance(inputs, (tuple, list)):
             if any(map(isvar, inputs)):
                 raise EarlyGoalError()
             return (eq, func(*inputs), out)
         else:
             return (eq, func(inputs), out)
Ejemplo n.º 38
0
def seteq(a, b, eq2=eq):
    """ Set Equality

    For example (1, 2, 3) set equates to (2, 1, 3)

    >>> from logpy import var, run, seteq
    >>> x = var()
    >>> run(0, x, seteq(x, (1, 2)))
    ((1, 2), (2, 1))

    >>> run(0, x, seteq((2, 1, x), (3, 1, 2)))
    (3,)
    """
    ts = lambda x: tuple(set(x))
    if not isvar(a) and not isvar(b):
        return permuteq(ts(a), ts(b), eq2)
    elif not isvar(a):
        return permuteq(ts(a), b, eq2)
    else:  # not isvar(b)
        return permuteq(a, ts(b), eq2)
Ejemplo n.º 39
0
def permuteq(a, b, eq2=eq):
    """ Equality under permutation

    For example (1, 2, 2) equates to (2, 1, 2) under permutation
    >>> from logpy import var, run, permuteq
    >>> x = var()
    >>> run(0, x, permuteq(x, (1, 2)))
    ((1, 2), (2, 1))

    >>> run(0, x, permuteq((2, 1, x), (2, 1, 2)))
    (2,)
    """
    if isinstance(a, tuple) and isinstance(b, tuple):
        if len(a) != len(b):
            return fail
        elif set(a) == set(b) and len(set(a)) == len(a):
            return success
        else:
            c, d = a, b
            try:
                c, d = tuple(sorted(c)), tuple(sorted(d))
            except:
                pass
            if len(c) == 1:
                return (eq2, c[0], d[0])
            return condeseq(
                ((eq2, c[i], d[0]), (permuteq, c[0:i] + c[i + 1:], d[1:], eq2))
                for i in range(len(c))
            )

    if isvar(a) and isvar(b):
        raise EarlyGoalError()

    if isvar(a) or isvar(b):
        if isinstance(b, tuple):
            c, d = a, b
        elif isinstance(a, tuple):
            c, d = b, a

        return (condeseq, ([eq(c, perm)]
                           for perm in unique(permutations(d, len(d)))))
Ejemplo n.º 40
0
Archivo: arith.py Proyecto: logpy/logpy
 def goal(x, y, z):
     if not isvar(x) and not isvar(y):
         return eq(op(x, y), z)
     if not isvar(y) and not isvar(z) and revop:
         return eq(x, revop(z, y))
     if not isvar(x) and not isvar(z) and revop:
         return eq(y, revop(z, x))
     raise EarlyGoalError()
Ejemplo n.º 41
0
def buildo(op, args, obj):
    """ obj is composed of op on args

    Example: in add(1,2,3) ``add`` is the op and (1,2,3) are the args

    Checks op_regsitry for functions to define op/arg relationships
    """
    if not isvar(obj):
        oop, oargs = op_args(obj)
        # TODO: Is greedy correct?
        return lallgreedy((eq, op, oop), (eq, args, oargs))
    else:
        try:
            return eq(obj, build(op, args))
        except TypeError:
            raise EarlyGoalError()
    raise EarlyGoalError()
Ejemplo n.º 42
0
def membero(x, coll):
    """ Goal such that x is an item of coll """
    if not isvar(coll):
        return (lany, ) + tuple((eq, x, item) for item in coll)
    raise EarlyGoalError()
Ejemplo n.º 43
0
 def lefto(q, p, lst):
     if isvar(lst):
         raise EarlyGoalError()
     return membero((q, p), zip(lst, lst[1:]))
Ejemplo n.º 44
0
Archivo: goals.py Proyecto: logpy/logpy
 def _nullo(s):
     _s = reify(l, s)
     if isvar(_s):
         yield unify(_s, None, s)
     elif is_null(_s):
         yield s
Ejemplo n.º 45
0
Archivo: arith.py Proyecto: logpy/logpy
def gt(x, y):
    """ x > y """
    if not isvar(x) and not isvar(y):
        return eq(x > y, True)
    else:
        raise EarlyGoalError()
Ejemplo n.º 46
0
Archivo: prime.py Proyecto: logpy/logpy
def primo(x):
    """ x is a prime number """
    if isvar(x):
        return condeseq([(eq, x, p)] for p in map(sg.prime, it.count(1)))
    else:
        return success if sg.isprime(x) else fail