我正在尝试使用prolog解决类似于Einsten问题的一组问题。
我的输入包含两个列表:
我可以轻松地解决这个问题:
puzzle(Spain,Italy,Germany,Volkswagen,Gm,Audi,X):-
Country = [Spain, Italy, Germany], ins(Country, 1..X), all_different(Country),
Brand = [Volkswagen, Gm, Audi], ins(Brand, 1..X), all_different(Brand),
Spain #= Gm + 1,
Germany #= Volkswagen,
Italy #= 2.
并致电:
275 ?- puzzle(Spain, Italy,Germany, Volkswagen, Gm, Audi,3).
Spain = Audi, Audi = 3,
Italy = Gm, Gm = 2,
Germany = Volkswagen, Volkswagen = 1.
我的问题:
总之,如何构建仅依赖于输入的解算器?
答案 0 :(得分:2)
简单易懂的翻译
puzzle(Ds, Cs, Symbols) :-
maplist(make_vars, Ds, Syms, Vars),
append(Syms, Symbols),
maplist(constraints(Symbols), Cs),
append(Vars, Store),
label(Store).
make_vars([domain(_)|Names], NamesVars, Vars) :-
length(Names, N),
length(Vars, N),
Vars ins 1 .. N,
all_distinct(Vars),
pairs_keys_values(NamesVars, Names, Vars).
constraints(Symbols, [=, L, R]) :-
expr(L, Symbols, X),
expr(R, Symbols, Y),
X #= Y.
expr(N, _, N) :- number(N).
expr(S, Symbols, X) :- memberchk(S-X, Symbols).
expr([+, L, R], Symbols, X + Y) :-
expr(L, Symbols, X),
expr(R, Symbols, Y).
产量
[volkswagen-1,gm-2,audi-3,germany-1,spain-3,italy-2]
expr / 3的简单推广:
expr([Op, L, R], Symbols, ClpF) :-
expr(L, Symbols, X),
expr(R, Symbols, Y),
ClpF =.. [Op, X, Y].
所以它接受其他二元运算符。类似的也可以应用于约束/ 2:
constraints(Symbols, [Op, L, R]) :-
expr(L, Symbols, X),
expr(R, Symbols, Y),
memberchk((Op, OpC), [(=, #=), (<, #<)]),
call(OpC, X, Y).
但请注意区别:constraints / 2 发布实际约束,而expr / 3只是翻译语法树。