Skip to content

Instantly share code, notes, and snippets.

@drm343
Last active February 15, 2022 05:27
Show Gist options
  • Save drm343/ac49ca68eea4646da671061432d00c0f to your computer and use it in GitHub Desktop.
Save drm343/ac49ca68eea4646da671061432d00c0f to your computer and use it in GitHub Desktop.
幫解問題 by minikanren with python3
#!/usr/bin/env python3
# pip install miniKanren
from unification import reify
from kanren import fact, facts, run, Var, conde, Relation, eq
from kanren.core import fail, succeed, lall, lany
base_item = Relation()
formula = Relation()
base_items = ["箭",
"爆發",
"焚燒",
"落石",
"巨大化",
"魔法齒輪"]
for item in base_items:
fact(base_item, item)
facts(formula,
["死亡之浪", ("大爆發", 1)],
["大爆發", ("魔法齒輪", 1)],
["大爆發", ("火箭炸彈", 1)],
["大爆發", ("流星雨", 1)],
["火箭炸彈", ("爆發之箭", 1)],
["火箭炸彈", ("同時射擊", 1)],
["爆發之箭", ("魔法齒輪", 1)],
["爆發之箭", ("弩", 1)],
["爆發之箭", ("爆發", 1)],
["弩", ("箭", 1)],
["弩", ("投石器", 1)],
["投石器", ("箭", 1)],
["投石器", ("巨大化", 1)],
["流星雨", ("隕石", 1)],
["流星雨", ("同時射擊", 1)],
["流星雨", ("爆發", 1)],
["隕石", ("爆發", 1)],
["隕石", ("焚燒", 1)],
["隕石", ("落石", 1)],
["同時射擊", ("箭", 2)])
def parent(q, name, z):
return formula(q, (name, z))
def composite_items(q, name, v, max_count = 0):
goal = [parent(q, name, v)]
if max_count >= 1:
tmp_var = []
for i in range(1, max_count + 1):
tmp = []
if len(tmp_var) < i:
tmp_var.append(Var())
for j in range(0, i):
if j == 0:
tmp.append(parent(q, tmp_var[j], Var()))
if j != 0:
tmp.append(parent(tmp_var[j - 1], tmp_var[j], Var()))
if j == i - 1:
tmp.append(parent(tmp_var[j], name, v))
goal.append(lall(*tmp))
return lany(*goal)
q = Var()
a = Var()
v = Var()
def counter(items):
result = {}
for item in items:
key = item[0]
value = item[1]
try:
result[key] = result[key] + value
except KeyError:
result[key] = value
return [result]
# 求出箭可以製作的道具
result = run(0, (q),
composite_items(q, "箭", Var(), max_count = 10),
results_filter = lambda x: list(set(x)))
print(result)
# 計算需要的基礎材料數量
result = run(0, (q, v),
eq(a, "死亡之浪"),
composite_items(a, q, v, max_count = 10),
base_item(q),
results_filter = counter)
print(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment