首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当目标/查询中的变量数量变化时如何求解- Prolog约束求解器

当目标/查询中的变量数量变化时如何求解- Prolog约束求解器
EN

Stack Overflow用户
提问于 2012-02-10 22:31:08
回答 2查看 232关注 0票数 0

以下是使用prolog约束求解机制解决经典SENDMORY密码算术问题的一个片段:

代码语言:javascript
复制
:- lib(ic).
sendmore(Digits) :-
Digits = [S,E,N,D,M,O,R,Y],
Digits :: [0..9],
alldifferent(Digits),
S #\= 0,
M #\= 0,
1000*S + 100*E + 10*N + D 
+ 1000*M + 100*O + 10*R + E
#= 10000*M + 1000*O + 100*N + 10*E + Y,
labeling(Digits).

现在,要执行此操作,我将像这样发送一个目标/查询:

代码语言:javascript
复制
?- sendmore(Digits).

这将为我返回数字的可能解决方案。

现在,我的问题是,我不想对变量(如S,E,N,...)进行“硬编码”。这样,但是目标/查询将给出变量的数量。例如,如果我传递的查询类似于:

代码语言:javascript
复制
?- sendmore(S,E,N,D,M).

然后,它应该只计算SENDM的值,并假设其他变量不适用,因此将这些变量赋值为0,然后继续计算。下一次查询时,我可能会在查询中传递不同数量的变量。例如:

代码语言:javascript
复制
?- sendmore(S,N,D,M,O,Y).

程序也应该进行同样的计算。

我试图实现的是上述场景的一个更通用的问题解决程序。在这方面的任何方向都是非常感谢的。我是prolog的新手,正在使用ECLIPSE约束解算器。谢谢。

EN

回答 2

Stack Overflow用户

发布于 2012-02-10 22:41:47

这里有两个想法:

sendmore您可以使用不同数量的参数来定义

  1. (),它将调用“真实”版本,并填充缺少的参数。但是你不能有不同的版本,有相同数量的参数但不同的参数(因为Prolog通过位置匹配args和参数)。
  2. 你可以扩展/复杂化你的列表格式,以允许指定你正在传递的参数;在你中间的例子中使用行[(s,S),(e,E),(n,N),(d,D),(m,M)]。有点单调乏味,但给你带来了你想要的灵活性。
票数 1
EN

Stack Overflow用户

发布于 2012-02-11 00:14:50

通常,目标中的变量和子句标题中的变量是通过它们的位置匹配的,而不是通过它们的名称匹配的。因此,调用?- sendmore0([S,E,N,D,M]).应该实现为:

代码语言:javascript
复制
sendmore0([S,E,N,D,M]) :- sendmore([S,E,N,D,M,_,_,_]).

但是,这意味着您需要为每种可能的组合实现此功能。

如果你真的想实现你所描述的东西,那么你需要给变量命名为稳定的。在ECLiPSe中,您可以使用库var_name来完成此操作。不过,这是一个相当不错的黑客行为。

代码语言:javascript
复制
:- lib(var_name).

sendmore0(L) :-
   build_arg(["S","E","N","D","M',"O","R","Y"], L, A),
   sendmore(A).

build_arg([], _, []) :- !.
build_arg([H|T], L, [HA|HT]) :-
   match_arg(L, H, HA),
   build_arg(T, L, HT).

match_arg([], _, _). % or use 0 as last argument if you want
match_arg([H|T], Base, A) :-
   (
      get_var_name(H, S),
      split_string(S,"#","",[Base,_])
   ->
      A = H
   ;
      match_arg(T, Base, A)
   ).

然后,您可以使用较短的变量列表调用sendmore0/1。别忘了设置变量名!

代码语言:javascript
复制
?- set_var_name(S, "S"), set_var_name(E, "E"), sendmore0([S, E]).
S = 9
E = 5
Yes (0.00s cpu, solution 1, maybe more)

免责声明:这是,而不是名称的用途。它们用于调试目的。如果约阿希姆看到这个,他会给我一个尖利的耳环...

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9229354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档