def missing(var, env): return disj( eq((), env), fresh( 3, lambda rest, sym, val: conjp( eq(Env(sym, val, rest), env), neq(sym, var), missing(var, rest), )), )
def jugs(states): return disj( eq([(0, 0, "")], states), fresh( 8, lambda big, small, act, prev_big, prev_small, tail, _, __: conjp( eq([(big, small, act), tail, ...], states), eq([(prev_big, prev_small, _), __, ...], tail), conde( [ conde( [ eq(small, prev_small), conde( [eq(big, BIG), eq(act, "fill big")], [eq(big, 0), eq(act, "empty big")])], [ fresh( lambda total: conjp( conde( [eq(big, BIG), eq(act, "to big")], [ eq(small, SMALL), eq(act, "to small")], [ eq(small, 0), neq(big, BIG), eq(act, "to big")], [ eq(big, 0), neq(small, SMALL), eq(act, "to small")]), add(big, small, total), add(prev_big, prev_small, total)))]), neq(big, prev_big)], [ eq(big, prev_big), conde( [eq(small, SMALL), eq(act, "fill small")], [eq(small, 0), eq(act, "empty small")]), neq(small, prev_small)]), gte(big, 0), lte(big, BIG), gte(small, 0), lte(small, SMALL), jugs(tail), )))
def lookup(o, v, x): return fresh( 3, lambda a, b, t: conj( eq(o, ((a, b), t)), conde( [eq(a, v), eq(b, TMono(x))], fresh( 3, lambda po, pb, pm: conjp( eq(a, v), eq(b, TPoly(po, pb)), infer(pb, po, x, pm), )), [neq(a, v), lookup(t, v, x)], )))
def main(): states = Var() big = Var() small = Var() _ = Var() __ = Var() for i in range(1, BIG + 1): p = conjp(eq([(big, small, _), __, ...], states), disj( eq(big, i), conj(neq(big, i), eq(small, i)), ), jugs(states)) for answer in run(1, states, p): print("{}:".format(i)) for b, s, a in reversed(answer): print(b, s, a) print()
def solve(): solutions = {} states = Var() big = Var() small = Var() _ = Var() __ = Var() for i in range(1, BIG + 1): p = conjp( eq([(big, small, _), __, ...], states), disj( eq(big, i), conj(neq(big, i), eq(small, i)), ), jugs(states) ) for answer in run(1, states, p): solutions[i] = list(reversed(answer)) return solutions
import pytest from mk.core import conj, eq, eqt from mk.disequality import neq, neqt from mk.run import initial from mk.stream import unfold from mk.unify import Var a = Var() b = Var() GOALS_DATA = [ (neq(a, 1), [{}]), (conj(eq(a, 1), neq(a, 2)), [{a: 1}]), (conj(eq(a, 1), neq(a, 1)), []), (conj(neq(a, 1), eq(a, 1)), []), (conj(conj(eq(a, 1), neq(a, b)), eqt(b, str)), [{a: 1}]), (neqt(a, int), [{}]), (conj(eq(a, 1), neqt(a, str)), [{a: 1}]), (conj(eqt(a, int), neqt(a, str)), [{}]), (conj(eq(a, 1), neqt(a, int)), []), (conj(eqt(a, int), neqt(a, int)), []), (conj(neqt(a, int), eq(a, 1)), []), (conj(neqt(a, int), eqt(a, int)), []), ] @pytest.mark.parametrize("goal, expected", GOALS_DATA) def test_disequality(goal, expected): assert [s for s, _, _ in unfold(goal(initial()))] == expected
def lookup(var, env, out): return fresh( 3, lambda rest, sym, val: conj( eq(Env(sym, val, rest), env), conde((eq(sym, var), eq(val, out)), (neq(sym, var), lookup(var, rest, out)))))