Prolog - 矩阵方程

3
我是Prolog的新手,想做这样的事情,但不知道从哪里开始。已经用Bounds库创建了矩阵,并检查数字是否小于9,但也就到此为止了,已经苦苦挣扎了几天。
它应该长这样:
2+7-4=5
+ - *
9-5*2=8
- + -
4*3-8=4
= = =
7 5 0

主要思路是给Prolog一个半填充的矩阵,以便他可以完成它。感谢您提前给我提供任何信息或想法。
一个解决方程的代码,通过放置具有给定数字的运算符:
:- use_module(library(bounds)).

lista([X])   --> [X].
lista([H|T]) --> [H], op, lista(T).

op --> [+].
op --> [-].
op --> [*].
op --> [/].
op --> [''].

puzzle(Num, Res) :-
   permutation(Num, Numbperm),
   lista(Numbperm, Lista, []),
   concat_atom([Res, =:=|Lista], At),
   term_to_atom(Ev, At),
   call(Ev),
   write(Ev), nl.

2
你已经有任何Prolog代码了吗?你尝试过什么?看一下CLP(fd)。 - vmg
1
添加了一段简短的代码,这是我目前所拥有的全部。@vmg - Jesús Bermúdez
1
通过阅读导览页面来获取更多信息。 - false
1个回答

2
为了使用,让我们使用library(clpfd),而不是library(bounds)
:- use_module(library(clpfd)).

我们可以这样陈述必须满足的约束条件:
m3x3_zs(Mss,Zs) :-
   Mss = [[M11,M12,M13], [M21,M22,M23], [M31,M32,M33]],
   Zs  = [ M11,M12,M13 ,  M21,M22,M23 ,  M31,M32,M33 ],
Zs ins 0..9,
5 #= M11+M12-M13, % 行约束 8 #= (M21-M22)*M23, % (有关详细信息,请参见下文) 4 #= M31*M32-M33,
7 #= M11+M21-M31, % 列约束 5 #= M12-M22+M23, 0 #= M13*M23-M33.
请注意上面突出显示的目标8 #= <b>(M21-M22)*M23</b>!如果我们使用常见的优先规则A-B*C,我们将得到8 #= M21-(M22*M23),但这将排除您在OP中提供的样本解决方案[[2,7,4],[9,5,2],[4,3,8]]
现在让我们通过使用枚举谓词labeling/2来搜索所有解决方案!
将一个 $3\times3$ 的矩阵转化为一个长度为 $9$ 的列表:
?- m3x3_zs(Mss,Zs), labeling([],Zs).
  Mss = [[0,5,0],[9,1,1],[2,2,0]], Zs = [0,5,0,9,1,1,2,2,0]
; Mss = [[0,5,0],[9,8,8],[2,2,0]], Zs = [0,5,0,9,8,8,2,2,0]
; Mss = [[0,7,2],[8,4,2],[1,8,4]], Zs = [0,7,2,8,4,2,1,8,4]
; Mss = [[0,8,3],[9,5,2],[2,5,6]], Zs = [0,8,3,9,5,2,2,5,6]
; Mss = [[1,4,0],[8,0,1],[2,2,0]], Zs = [1,4,0,8,0,1,2,2,0]
; Mss = [[1,4,0],[8,7,8],[2,2,0]], Zs = [1,4,0,8,7,8,2,2,0]
; Mss = [[1,5,1],[9,8,8],[3,4,8]], Zs = [1,5,1,9,8,8,3,4,8]
; Mss = [[1,6,2],[7,3,2],[1,8,4]], Zs = [1,6,2,7,3,2,1,8,4]
; Mss = [[1,7,3],[8,4,2],[2,5,6]], Zs = [1,7,3,8,4,2,2,5,6]
; Mss = [[1,8,4],[9,5,2],[3,4,8]], Zs = [1,8,4,9,5,2,3,4,8]
; Mss = [[2,3,0],[7,6,8],[2,2,0]], Zs = [2,3,0,7,6,8,2,2,0]
; Mss = [[2,4,1],[8,7,8],[3,4,8]], Zs = [2,4,1,8,7,8,3,4,8]
; Mss = [[2,5,2],[6,2,2],[1,8,4]], Zs = [2,5,2,6,2,2,1,8,4]
; Mss = [[2,6,3],[7,3,2],[2,5,6]], Zs = [2,6,3,7,3,2,2,5,6]
; Mss = [[2,7,4],[8,4,2],[3,4,8]], Zs = [2,7,4,8,4,2,3,4,8]
; Mss = [[3,2,0],[6,5,8],[2,2,0]], Zs = [3,2,0,6,5,8,2,2,0]
; Mss = [[3,3,1],[7,6,8],[3,4,8]], Zs = [3,3,1,7,6,8,3,4,8]
; Mss = [[3,4,2],[5,1,2],[1,8,4]], Zs = [3,4,2,5,1,2,1,8,4]
; Mss = [[3,5,3],[6,2,2],[2,5,6]], Zs = [3,5,3,6,2,2,2,5,6]
; Mss = [[3,6,4],[7,3,2],[3,4,8]], Zs = [3,6,4,7,3,2,3,4,8]
; Mss = [[4,1,0],[5,4,8],[2,2,0]], Zs = [4,1,0,5,4,8,2,2,0]
; Mss = [[4
需要再具体一点吗?哪些解决方案中间有数字 4
将上述代码翻译成中文:
?- m3x3_zs(Mss,Zs), Mss=[_,[_,4,_],_], labeling([],Zs).
  给定一个3x3的矩阵Mss和一个变量Zs,其中Mss的第二行中间的数为4。
  使用labeling函数对Zs进行赋值,使得Zs是Mss的扁平化结果。
  执行结果会输出多个解,每个解对应一个符合要求的矩阵Mss和扁平化后的Zs。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接