Last active
February 15, 2022 05:27
-
-
Save drm343/ac49ca68eea4646da671061432d00c0f to your computer and use it in GitHub Desktop.
幫解問題 by minikanren with python3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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