Exemplo n.º 1
0
def sudoku_solver(hints):
    variables = vars(hints)
    rows = get_rows(variables)
    cols = get_columns(rows)
    sqs = get_squares(rows)
    return run(
        1,
        variables,
        lall(*(all_numbers(r) for r in rows)),
        lall(*(all_numbers(c) for c in cols)),
        lall(*(all_numbers(s) for s in sqs)),
    )
Exemplo n.º 2
0
def non_obs_graph_applyo(relation, a, b):
    """Construct a goal that applies a relation to all nodes above an observed random variable.

    This is useful if you don't want to apply relations to an observed random
    variable, but you do want to apply them to every term above one and
    ultimately reproduce the entire graph (observed RV included).

    Parameters
    ----------
    relation: function
      A binary relation/goal constructor function
    a: lvar or meta graph
      The left-hand side of the relation.
    b: lvar or meta graph
      The right-hand side of the relation

    """
    obs_lv, obs_rv_lv = var(), var()
    rv_op_lv, rv_args_lv, obs_rv_lv = var(), var(), var()
    new_rv_args_lv, new_obs_rv_lv = var(), var()
    return lall(
        # Indicate the observed term (i.e. observation and RV)
        eq(a, mt.observed(obs_lv, obs_rv_lv)),
        # Deconstruct the observed random variable
        (buildo, rv_op_lv, rv_args_lv, obs_rv_lv),
        # Apply relation to the RV's inputs
        seq_apply_anyo(
            partial(tt_graph_applyo, relation), rv_args_lv, new_rv_args_lv, skip_op=False
        ),
        # Reconstruct the random variable
        (buildo, rv_op_lv, new_rv_args_lv, new_obs_rv_lv),
        # Reconstruct the observation
        (buildo, mt.observed, etuple(obs_lv, new_obs_rv_lv), b),
    )
Exemplo n.º 3
0
    def reduceo_goal(s):

        nonlocal in_term, out_term

        in_term_rf, out_term_rf = reify((in_term, out_term), s)

        # The result of reducing the input graph once
        term_rdcd = var()

        # Are we working "backward" and (potentially) "expanding" a graph
        # (e.g. when the relation is a reduction rule)?
        is_expanding = isvar(in_term_rf)

        # One application of the relation assigned to `term_rdcd`
        single_apply_g = (relation, in_term, term_rdcd)

        # Assign/equate (unify, really) the result of a single application to
        # the "output" term.
        single_res_g = eq(term_rdcd, out_term)

        # Recurse into applications of the relation (well, produce a goal that
        # will do that)
        another_apply_g = reduceo(relation, term_rdcd, out_term)

        # We want the fixed-point value to show up in the stream output
        # *first*, but that requires some checks.
        if is_expanding:
            # When an un-reduced term is a logic variable (e.g. we're
            # "expanding"), we can't go depth first.
            # We need to draw the association between (i.e. unify) the reduced
            # and expanded terms ASAP, in order to produce finite
            # expanded graphs first and yield results.
            #
            # In other words, there's no fixed-point to produce in this
            # situation.  Instead, for example, we have to produce an infinite
            # stream of terms that have `out_term` as a fixed point.
            # g = conde([single_res_g, single_apply_g],
            #           [another_apply_g, single_apply_g])
            g = lall(conde([single_res_g], [another_apply_g]), single_apply_g)
        else:
            # Run the recursion step first, so that we get the fixed-point as
            # the first result
            g = lall(single_apply_g, conde([another_apply_g], [single_res_g]))

        g = goaleval(g)
        yield from g(s)
    def binopo_goal(S: ConstrainedState):
        nonlocal x, y, v, op

        uuid = str(uuid4())[:4]
        t = var("type_" + uuid)
        x_rf, y_rf, v_rf, op_rf = reify((x, y, v, op), S)
        isground_all = [
            isground(reified_value, S)
            for reified_value in [x_rf, y_rf, v_rf, op_rf]
        ]
        if not all(isground_all):
            # We can only fix one LV at a time
            if len([uv for uv in isground_all if uv is False]) == 1:
                # TODO: Revop the other vars
                if not isground(v_rf, S):
                    try:
                        g = lall(
                            isinstanceo(x_rf, t),
                            isinstanceo(y_rf, t),
                            isinstanceo(v_rf, t),
                            eq(op_rf(x_rf, y_rf), v_rf),
                        )
                    except Exception as e:
                        logger.debug(
                            "Got exception during binop with args {}: {}".
                            format([x_rf, y_rf, v_rf, op_rf], e))
                        return
                    yield from g(S)
        else:
            # TODO: Why isnt this covered by the `typeo` goal?
            try:
                g = lall(
                    isinstanceo(x_rf, t),
                    isinstanceo(y_rf, t),
                    isinstanceo(v_rf, t),
                    eq(op_rf(x_rf, y_rf), v_rf),
                )
            except Exception as e:
                logger.debug(
                    "Got exception during ungrounded binop with args {}: {}".
                    format([x_rf, y_rf, v_rf, op_rf], e))
                return
            yield from g(S)
Exemplo n.º 5
0
    def mul_trans(in_expr, out_expr):
        """Equate `2 * x` with `5 * x` in a Theano `scan`.

        I.e. from left-to-right, replace `2 * x[t-1]` with `5 * x[t-1]`.
        """
        arg_lv = var()
        inputs_lv, info_lv = var(), var()
        in_scan_lv = mt.Scan(inputs_lv, [mt.mul(2, arg_lv)], info_lv)
        out_scan_lv = mt.Scan(inputs_lv, [mt.mul(5, arg_lv)], info_lv)

        return lall(eq(in_expr, in_scan_lv), eq(out_expr, out_scan_lv))
Exemplo n.º 6
0
 def distributes(in_lv, out_lv):
     return lall(
         # lhs == A * (x + b)
         eq(etuple(mt.dot, var("A"), etuple(mt.add, var("x"), var("b"))),
            etuplize(in_lv)),
         # rhs == A * x + A * b
         eq(
             etuple(mt.add, etuple(mt.dot, var("A"), var("x")),
                    etuple(mt.dot, var("A"), var("b"))),
             out_lv,
         ),
     )
Exemplo n.º 7
0
 def distributes(in_lv, out_lv):
     A_lv, x_lv, y_lv, z_lv = vars(4)
     return lall(
         # lhs == A * (x + y + z)
         eq_assoccomm(
             etuple(_dot, A_lv,
                    etuple(at.add, x_lv, etuple(at.add, y_lv, z_lv))),
             in_lv,
         ),
         # This relation does nothing but provide us with a means of
         # generating associative-commutative matches in the `kanren`
         # output.
         eq((A_lv, x_lv, y_lv, z_lv), out_lv),
     )
Exemplo n.º 8
0
def normal_normal_regression(Y, X, beta, Y_args_tail=None, beta_args=None):
    """Create a goal for a normal-normal regression of the form `Y ~ N(X * beta, sd**2)`."""
    Y_args_tail = Y_args_tail or var()
    beta_args = beta_args or var()

    Y_args, Y_mean_lv = var(), var()

    res = lall(
        # `Y` is a `NormalRV`
        applyo(mt.NormalRV, Y_args, Y),
        # `beta` is also a `NormalRV`
        applyo(mt.NormalRV, beta_args, beta),
        # Obtain its mean parameter and remaining args
        applyo(Y_mean_lv, Y_args_tail, Y_args),
        # Relate it to a dot product of `X` and `beta`
        applyo(mt.dot, etuple(X, beta), Y_mean_lv),
    )

    return res
Exemplo n.º 9
0
def test_ifa():
    x, y = var(), var()

    assert run(0, (x, y), ifa(lall(eq(x, True), eq(y, 1)),
                              eq(y, 2))) == ((True, 1), )
    assert run(0, y, eq(x, False),
               ifa(lall(eq(x, True), eq(y, 1)), lall(eq(y, 2)))) == (2, )
    assert (run(
        0,
        y,
        eq(x, False),
        ifa(lall(eq(x, True), eq(y, 1)), lall(eq(x, True), eq(y, 2))),
    ) == ())

    assert run(
        0,
        y,
        eq(x, True),
        ifa(lall(eq(x, True), eq(y, 1)), lall(eq(x, True), eq(y, 2))),
    ) == (1, )
Exemplo n.º 10
0
accounts = (Account('Adam', 'Smith', 1,
                    20), Account('Carl', 'Marx', 2,
                                 3), Account('John', 'Rockefeller', 3, 1000))

# optional name strings are helpful for debugging
first = var('first')
last = var('last')
ident = var('ident')
balance = var('balance')
newbalance = var('newbalance')

# Describe a couple of transformations on accounts
source = Account(first, last, ident, balance)
target = Account(first, last, ident, newbalance)

theorists = ('Adam', 'Carl')
# Give $10 to theorists
theorist_bonus = lall((membero, source, accounts), (membero, first, theorists),
                      (add, 10, balance, newbalance))

# Take $10 from anyone with more than $100
tax_the_rich = lall((membero, source, accounts), (gt, balance, 100),
                    (sub, balance, 10, newbalance))

print("Take $10 from anyone with more than $100")
print((run(0, target, tax_the_rich)))

print("Give $10 to theorists")
print((run(0, target, theorist_bonus)))
Exemplo n.º 11
0

houses = var()

rules_zebraproblem = lall(
    (eq, (var(), var(), var(), var(), var()), houses),
    (membero, ('Englishman', var(), var(), var(), 'red'), houses),
    (membero, ('Swede', var(), var(), 'dog', var()), houses),
    (membero, ('Dane', var(), 'tea', var(), var()), houses),
    (left, (var(), var(), var(), var(), 'green'),
     (var(), var(), var(), var(), 'white'), houses),
    (membero, (var(), var(), 'coffee', var(), 'green'), houses),
    (membero, (var(), 'Pall Mall', var(), 'birds', var()), houses),
    (membero, (var(), 'Dunhill', var(), var(), 'yellow'), houses),
    (eq, (var(), var(),
          (var(), var(), 'milk', var(), var()), var(), var()), houses),
    (eq, (('Norwegian', var(), var(), var(), var()), var(), var(), var(),
          var()), houses), (next, (var(), 'Blend', var(), var(), var()),
                            (var(), var(), var(), 'cats', var()), houses),
    (next, (var(), 'Dunhill', var(), var(), var()),
     (var(), var(), var(), 'horse', var()), houses),
    (membero, (var(), 'Blue Master', 'beer', var(), var()), houses),
    (membero, ('German', 'Prince', var(), var(), var()), houses),
    (next, ('Norwegian', var(), var(), var(), var()),
     (var(), var(), var(), var(), 'blue'), houses),
    (next, (var(), 'Blend', var(), var(), var()),
     (var(), var(), 'water', var(), var()), houses),
    (membero, (var(), var(), var(), 'zebra', var()), houses))

#run solver with preceeding constraints
solutions = run(0, houses, rules_zebraproblem)
Exemplo n.º 12
0
)

# optional name strings are helpful for debugging
first = var("first")
last = var("last")
ident = var("ident")
balance = var("balance")
newbalance = var("newbalance")

# Describe a couple of transformations on accounts
source = Account(first, last, ident, balance)
target = Account(first, last, ident, newbalance)

theorists = ("Adam", "Carl")
# Give $10 to theorists
theorist_bonus = lall(
    membero(source, accounts),
    membero(first, theorists),
    add(10, balance, newbalance),
)

# Take $10 from anyone with more than $100
tax_the_rich = lall(membero(source, accounts), gt(balance, 100),
                    sub(balance, 10, newbalance))

print("Take $10 from anyone with more than $100")
print(run(0, target, tax_the_rich))

print("Give $10 to theorists")
print(run(0, target, theorist_bonus))
Exemplo n.º 13
0
# optional name strings are helpful for debugging
first = var(prefix="first")
last = var(prefix="last")
ident = var(prefix="ident")
balance = var(prefix="balance")
newbalance = var(prefix="newbalance")

# Describe a couple of transformations on accounts
source = Account(first, last, ident, balance)
target = Account(first, last, ident, newbalance)

theorists = ("Adam", "Carl")
# Give $10 to theorists
theorist_bonus = lall(
    membero(source, accounts),
    membero(first, theorists),
    applyo(add, (10, balance), newbalance),
)

# Take $10 from anyone with more than $100
a = var(prefix="a")
tax_the_rich = lall(
    membero(source, accounts),
    applyo(gt, (balance, 100), a),
    eq(a, True),
    applyo(sub, (balance, 10), newbalance),
)

print("Take $10 from anyone with more than $100")
print(run(0, target, tax_the_rich))
Exemplo n.º 14
0
# Define the rules
rules = lall(
    # There are 4 people
    (eq, (var(), var(), var(), var()), people),

    # Steve's car is blue
    (membero, ('Steve', var(), 'blue', var()), people),

    # Person who owns the cat lives in Canada
    (membero, (var(), 'cat', var(), 'Canada'), people),

    # Matthew lives in USA
    (membero, ('Matthew', var(), var(), 'USA'), people),

    # The person who has a black car lives in Australia
    (membero, (var(), var(), 'black', 'Australia'), people),

    # Jack has a cat
    (membero, ('Jack', 'cat', var(), var()), people),

    # Alfred lives in Australia
    (membero, ('Alfred', var(), var(), 'Australia'), people),

    # Person who owns the dog lives in France
    (membero, (var(), 'dog', var(), 'France'), people),

    # Who is the owner of the rabbit?
    (membero, (var(), 'rabbit', var(), var()), people)
)

# Run the solver
Exemplo n.º 15
0
clues = lall(
    # Solution with 4 fields: Title, LastName, Product and Priority
    (eq, (var(), var(), var(), var()), customer),
    # All Values
    (membero, ('Baroness', var(), var(), var()), customer),
    (membero, ('Sergeant', var(), var(), var()), customer),
    (membero, ('Reverend', var(), var(), var()), customer),
    (membero, ('Doctor', var(), var(), var()), customer),
    (membero, (var(), 'Bevens', var(), var()), customer),
    (membero, (var(), 'Shadwell', var(), var()), customer),
    (membero, (var(), 'Dimmadome', var(), var()), customer),
    (membero, (var(), 'Rotzenheimer', var(), var()), customer),
    (membero, (var(), var(), 'Rose Bar', var()), customer),
    (membero, (var(), var(), 'Lemon Gel', var()), customer),
    (membero, (var(), var(), 'Chamomile Bar', var()), customer),
    (membero, (var(), var(), 'Hibiscus Soap-on-a-Rope', var()), customer),
    (membero, (var(), var(), var(), '1'), customer),
    (membero, (var(), var(), var(), '2'), customer),
    (membero, (var(), var(), var(), '3'), customer),
    (membero, (var(), var(), var(), '4'), customer),
    # Priority 1 > 2 > 3 > 4
    (higher, (var(), var(), var(), '1'), (var(), var(), var(), '2'), customer),
    (higher, (var(), var(), var(), '2'), (var(), var(), var(), '3'), customer),
    (higher, (var(), var(), var(), '3'), (var(), var(), var(), '4'), customer),
    # Clue1a  customer with the highest priority has a title and last name that begin with the same letter
    (any4, ('Baroness', 'Bevens', var(), '1'),
     ('Reverend', 'Rotzenheimer', var(), '1'),
     ('Sergeant', 'Shadwell', var(), '1'),
     ('Doctor', 'Dimmadome', var(), '1'), customer),
    # Clue2a Bevens' priority is directly after Dimmadome
    (higher, (var(), 'Dimmadome', var(), var()),
     (var(), 'Bevens', var(), var()), customer),
    # Clue6 The priority of the person who ordered the Rose Bar is directly after the person who ordered the Lemon Gel.
    (higher, (var(), var(), 'Lemon Gel', var()),
     (var(), var(), 'Rose Bar', var()), customer),
    # Clue2b Neither of these people ordered the Chamomile Bar or the Hibiscus Soap-on-a-Rope.
    (any2, (var(), 'Dimmadome', 'Rose Bar', var()),
     (var(), 'Dimmadome', 'Lemon Gel', var()), customer),
    (any2, (var(), 'Bevens', 'Rose Bar', var()),
     (var(), 'Bevens', 'Lemon Gel', var()), customer),
    # Clue3 The Sergeant and the person who ordered Lemon Gel are either 1st priority or 3rd priority
    (any2, ('Sergeant', var(), var(), '1'),
     ('Sergeant', var(), var(), '3'), customer),
    (any2, (var(), var(), 'Lemon Gel', '1'),
     (var(), var(), 'Lemon Gel', '3'), customer),
    # Clue4a The Reverend didn't order the Rose Bar.
    (any3, ('Reverend', var(), 'Lemon Gel', var()),
     ('Reverend', var(), 'Chamomile Bar', var()),
     ('Reverend', var(), 'Hibiscus Soap-on-a-Rope', var()), customer),
    # Clue4b And the Reverend isn't 2nd priority.
    (any3, ('Reverend', var(), var(), '1'), ('Reverend', var(), var(), '3'),
     ('Reverend', var(), var(), '4'), customer),
    # Clue5 The Sergeant either ordered Hibiscus Soap-on-a-Rope or is 4th priority.
    (any2, ('Sergeant', var(), 'Hibiscus Soap-on-a-Rope', var()),
     ('Sergeant', var(), var(), '4'), customer),
    # Clue7a Dimmadome is not a Doctor
    (any3, ('Baroness', 'Dimmadome', var(), var()),
     ('Sergeant', 'Dimmadome', var(), var()),
     ('Reverend', 'Dimmadome', var(), var()), customer),
    # Clue7b the Baroness didn't order the Hibiscus Soap-on-a-Rope.
    (any3, ('Baroness', var(), 'Rose Bar', var()),
     ('Baroness', var(), 'Lemon Gel', var()),
     ('Baroness', var(), 'Chamomile Bar', var()), customer))
Exemplo n.º 16
0
def solve(n, expr, env, value, maxdepth=3):
    goals = eval_expro(expr, env, value, depth=0, maxdepth=maxdepth)
    results = map(partial(reify, expr), goaleval(lall(goals))({}))
    return take(n, unique(results, key=multihash))
Exemplo n.º 17
0
def normal_qr_transform(in_expr, out_expr):
    """Produce a relation for normal-normal regression and its QR-reduced form.

    TODO XXX: This isn't entirely correct (e.g. it needs to also
    transform the variance terms), but it demonstrates all the requisite
    functionality for this kind of model reformulation.

    """
    y_lv, Y_lv, X_lv, beta_lv = var(), var(), var(), var()
    Y_args_lv, beta_args_lv = var(), var()
    QR_lv, Q_lv, R_lv = var(), var(), var()
    beta_til_lv, beta_new_lv = var(), var()
    beta_mean_lv, beta_sd_lv = var(), var()
    beta_size_lv, beta_rng_lv = var(), var()
    Y_new_lv = var()
    X_op_lv = var()

    in_expr = etuplize(in_expr)

    res = lall(
        # Only applies to regression models on observed RVs
        eq(in_expr, etuple(mt.observed, y_lv, Y_lv)),
        # Relate the model components
        normal_normal_regression(Y_lv, X_lv, beta_lv, Y_args_lv, beta_args_lv),
        # Let's not do all this to an already QR-reduce graph;
        # otherwise, we'll loop forever!
        applyo(X_op_lv, var(), X_lv),
        # XXX: This type of dis-equality goal isn't the best,
        # but it will definitely work for now.
        neq(mt.nlinalg.qr_full, X_op_lv),
        # Relate terms for the QR decomposition
        eq(QR_lv, etuple(mt.nlinalg.qr_full, X_lv)),
        eq(Q_lv, etuple(itemgetter(0), QR_lv)),
        eq(R_lv, etuple(itemgetter(1), QR_lv)),
        # The new `beta_tilde`
        eq(beta_args_lv, (beta_mean_lv, beta_sd_lv, beta_size_lv, beta_rng_lv)),
        eq(
            beta_til_lv,
            etuple(
                mt.NormalRV,
                # Use these `tt.[ones|zeros]_like` functions to preserve the
                # correct shape (and a valid `tt.dot`).
                etuple(mt.zeros_like, beta_mean_lv),
                etuple(mt.ones_like, beta_sd_lv),
                beta_size_lv,
                beta_rng_lv,
            ),
        ),
        # Relate the new and old coeffs
        eq(beta_new_lv, etuple(mt.dot, etuple(mt.nlinalg.matrix_inverse, R_lv), beta_til_lv)),
        # Use the relation the other way to produce the new/transformed
        # observation distribution
        normal_normal_regression(Y_new_lv, Q_lv, beta_til_lv, Y_args_lv),
        eq(
            out_expr,
            [
                (
                    in_expr,
                    etuple(mt.observed, y_lv, etuple(update_name_suffix, Y_new_lv, Y_lv, "")),
                ),
                (beta_lv, beta_new_lv),
            ],
        ),
    )
    return res
Exemplo n.º 18
0
def test_lall():
    x = var()
    assert results(lall(eq(x, 2))) == ({x: 2}, )
    assert results(lall(eq(x, 2), eq(x, 3))) == ()
    assert results(lall()) == ({}, )
    assert run(0, x, lall()) == (x, )
Exemplo n.º 19
0
                                 3), Account('John', 'Rockefeller', 3, 1000))

# optional name strings are helpful for debugging
first = var('first')
last = var('last')
ident = var('ident')
balance = var('balance')
newbalance = var('newbalance')

# Describe a couple of transformations on accounts
source = Account(first, last, ident, balance)
target = Account(first, last, ident, newbalance)

theorists = ('Adam', 'Carl')
# Give $10 to theorists
theorist_bonus = lall((membero, source, accounts), (membero, first, theorists),
                      (add, 10, balance, newbalance))

# Take $10 from anyone with more than $100
tax_the_rich = lall((membero, source, accounts), (gt, balance, 100),
                    (sub, balance, 10, newbalance))

print("Take $10 from anyone with more than $100")
print((run(0, target, tax_the_rich)))

print("Give $10 to theorists")
print((run(0, target, theorist_bonus)))

stimulus = (Account('Donald', 'Trump', 4,
                    362000000), Account('Jon', 'Snow', 5, 65000),
            Account('Lebron James', 'Smith', 6,
                    37000000), Account('Naruto', 'Uzumaki', 7, 43000))
Exemplo n.º 20
0
            Account('Carl', 'Marx', 2, 3),
            Account('John', 'Rockefeller', 3, 1000))

# optional name strings are helpful for debugging
first = var('first')
last = var('last')
ident = var('ident')
balance = var('balance')
newbalance = var('newbalance')

# Describe a couple of transformations on accounts
source = Account(first, last, ident, balance)
target = Account(first, last, ident, newbalance)

theorists = ('Adam', 'Carl')
# Give $10 to theorists
theorist_bonus = lall((membero, source, accounts),
                      (membero, first, theorists),
                      (add, 10, balance, newbalance))

# Take $10 from anyone with more than $100
tax_the_rich = lall((membero, source, accounts),
                    (gt, balance, 100),
                    (sub, balance, 10, newbalance))

print("Take $10 from anyone with more than $100")
print((run(0, target, tax_the_rich)))

print("Give $10 to theorists")
print((run(0, target, theorist_bonus)))
Exemplo n.º 21
0
    def bad_relation():
        def _bad_relation(s):
            raise SomeException("some exception")

        return lall(_bad_relation)