performance - 在Prolog中更快地执行口头算术

标签 performance prolog logic clpfd cryptarithmetic-puzzle

我已经在Prolog中制作了一个可以使用的通用verbal arithmetic求解器,但是它太慢了。运行简单表达式S E N D + M O R E = M O N E Y只需8分钟。有人可以帮助我使其运行得更快吗?

/* verbalArithmetic(List,Word1,Word2,Word3) where List is the list of all 
   possible letters in the words. The SEND+MORE = MONEY expression would then
   be represented as
    verbalArithmetic([S,E,N,D,M,O,R,Y],[S,E,N,D],[M,O,R,E],[M,O,N,E,Y]). */

validDigit(X) :- member(X,[0,1,2,3,4,5,6,7,8,9]).
validStart(X) :- member(X,[1,2,3,4,5,6,7,8,9]).
assign([H|[]]) :- validDigit(H).         
assign([H|Tail]) :- validDigit(H), assign(Tail), fd_all_different([H|Tail]).

findTail(List,H,T) :- append(H,[T],List).

convert([T],T) :- validDigit(T).
convert(List,Num) :- findTail(List,H,T), convert(H,HDigit), Num is (HDigit*10+T).

verbalArithmetic(WordList,[H1|Tail1],[H2|Tail2],Word3) :- 
    validStart(H1), validStart(H2), assign(WordList), 
    convert([H1|Tail1],Num1),convert([H2|Tail2],Num2), convert(Word3,Num3), 
    Sum is Num1+Num2, Num3 = Sum.

最佳答案

考虑在SWI-Prolog中使用finite domain constraints:

:- use_module(library(clpfd)).

puzzle([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]) :-
        Vars = [S,E,N,D,M,O,R,Y],
        Vars ins 0..9,
        all_different(Vars),
                  S*1000 + E*100 + N*10 + D +
                  M*1000 + O*100 + R*10 + E #=
        M*10000 + O*1000 + N*100 + E*10 + Y,
        M #\= 0, S #\= 0.

查询示例:
?- time((puzzle(As+Bs=Cs), label(As))).
% 5,803 inferences, 0.002 CPU in 0.002 seconds (98% CPU, 3553582 Lips)
As = [9, 5, 6, 7],
Bs = [1, 0, 8, 5],
Cs = [1, 0, 6, 5, 2] ;
% 1,411 inferences, 0.001 CPU in 0.001 seconds (97% CPU, 2093472 Lips)
false.

关于performance - 在Prolog中更快地执行口头算术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10925285/

相关文章:

Java数学逻辑错误

javascript - 为什么推荐 jQuery.ready 这么慢?

mysql - MySQL大表数据恢复性能

python - 按键(整数)对字典进行有效排序,返回排序的值列表

regex - Prolog 中的正则表达式

module - SWI-Prolog 中的跨模块 "interface"调用

algorithm - 大O,您如何计算/近似?

prolog - 在 Prolog 中制表,什么时候存储值?

sql - 基于以前的值更新 SQL SERVER 2005

Java++运算符