Prolog 如何处理这个问题;“多重循环”;在序言中?

Prolog 如何处理这个问题;“多重循环”;在序言中?,prolog,Prolog,因此,我基本上是在尝试编写一个Prolog代码,模拟多个循环: int foo() { int i, j, m; m = 1; i = 0; for (; i < 5; i++) { j = 0; for (; j < 5; j++) m = i + j + m; } return m; } intfoo() { int i,j,m; m=1; i=0; 对于(;i

因此,我基本上是在尝试编写一个
Prolog
代码,模拟多个循环:

int foo()
{
   int i, j, m;
   m = 1;
   i = 0;
   for (; i < 5; i++)
   {
      j = 0;
      for (; j < 5; j++)
         m = i + j + m;
   }

   return m;
}
intfoo()
{
int i,j,m;
m=1;
i=0;
对于(;i<5;i++)
{
j=0;
对于(;j<5;j++)
m=i+j+m;
}
返回m;
}
我的序言代码如下:

foo(M02) :-
   M01 is 1,
   I01 is 0,
   loop_entry_1(M01, J01, I01, M02, J02, I02).

loop_entry_1(M01, J01, I01, FinalM, FinalJ, FinalI) :-
   I01 < 5, !,
   J01 is 0,                    %%  I failed here!!
   loop_entry_0(M01, J01, I01, M02, J02, I01),
   I02 is I01 + 1,
   loop_entry_1( M02, J02, I02 , FinalM, FinalJ, FinalI).
loop_entry_1( M01, J01, I01,  M01, J01, I01).

loop_entry_0(M01, J01, I01, FinalM, FinalJ, FinalI) :-
   J01 < 5, !,
   M02 is (I01 + J01) + M01,
   J02 is J01 + 1,
   loop_entry_0(M02, J02, I01 , FinalM, FinalJ, FinalI).
loop_entry_0(M01, J01, I01,  M01, J01, I01). 
foo(M02):-
M01是1,
I01是0,
循环输入(M01、J01、I01、M02、J02、I02)。
循环输入(M01、J01、I01、FinalM、FinalJ、FinalI):-
I01<5!,
J01是0,%%我在这里失败了!!
循环输入(M01,J01,I01,M02,J02,I01),
I02是I01+1,
循环输入1(M02、J02、I02、FinalM、FinalJ、FinalI)。
循环输入(M01、J01、I01、M01、J01、I01)。
循环输入(M01、J01、I01、FinalM、FinalJ、FinalI):-
J01<5!,
M02是(I01+J01)+M01,
J02是J01+1,
循环输入0(M02、J02、I01、FinalM、FinalJ、FinalI)。
循环输入(M01、J01、I01、M01、J01、I01)。
因此,问题在于,每次执行退出
循环进入\u 0
时,
J01
已分配给
5
,它将在
J01为0
时失败

但我就是想不出一个办法来处理这个问题


谁能给我一些帮助吗?

您正在尝试在Prolog中模拟状态。您已经了解了如何做到这一点:本质上,通过一系列逻辑变量,您可以模拟单个(非逻辑)变量。这种模拟通常被称为“差异”。通常的惯例是这样命名这些变量:
S0、S1、S2。。。S
。所以“最终”状态没有任何数字。通过这种方式,您可以在不知道需要多少中间状态的情况下启动规则,例如:

p(S0, S) :-
   ...
所以每次你给一个变量赋值时,你也需要一个新的逻辑变量。但是,你说J01是0!等等,我们说:新的状态意味着新的变量!因此,您必须在这里引入一个新的中间变量,或者在下一个目标中将
J01
替换为
0

与差异相关的另一个常见惯例是将相关论点紧跟在对方之后

然后,虽然这不是经常练习的,但是你可以省略这些论点之间的空格,这样它们就可以更好地显示它们是属于彼此的

哦,我忘了:循环中碰巧是常量的变量不需要复制

因此,使用所有这些约定,
foo/1
将被编写(注意不同的参数顺序!):

foo(M):-
循环项1(1,M,0,u)。
循环输入(M0,M,I0,I):-
I0<5!,
循环输入(M0,M1,0,I0),
I1是I0+1,
循环输入(M1,M,I1,I)。
循环输入1(M,M,I,I)。
循环输入(M0,M,J0,J,I):-
J0<5!,
M1是I+J0+M0,
J1为J0+1,
循环输入(M1,M,J1,J,I)。
循环项0(M,M,J,J,0)。
但是,我意识到,我们可以完全删除一些状态变量。事实上:

foo(M) :-
   loop_entry_1(1,M, 0).

loop_entry_1(M0,M, I0) :-
   I0 < 5, !,
   loop_entry_0(M0,M1, 0, I0),
   I1 is I0+1,
   loop_entry_1(M1,M, I1).
loop_entry_1(M,M, _).

loop_entry_0(M0,M, J0, I) :-
   J0 < 5, !,
   M1 is I + J0 + M0,
   J1 is J0 + 1,
   loop_entry_0(M1,M, J1, I).
loop_entry_0(M,M, _, _). 
foo(M):-
循环输入1(1,M,0)。
循环输入1(M0,M,I0):-
I0<5!,
循环输入(M0,M1,0,I0),
I1是I0+1,
循环输入(M1,M,I1)。
循环输入1(M,M,u)。
循环输入(M0,M,J0,I):-
J0<5!,
M1是I+J0+M0,
J1为J0+1,
循环输入0(M1,M,J1,I)。
循环项0(M,M,u,u,u)。
所以这是另一个技巧:如果您只需要一个简单的尾部递归函数中的状态,那么您可以忽略第二个参数!参数之间的间距对于区分复杂状态(M)和简单状态而言并不重要



我真的应该补充一点:这种1对1的翻译可能会很有趣,但不会对具体问题提供很多见解。

太棒了!谢谢:)
foo(M) :-
   loop_entry_1(1,M, 0).

loop_entry_1(M0,M, I0) :-
   I0 < 5, !,
   loop_entry_0(M0,M1, 0, I0),
   I1 is I0+1,
   loop_entry_1(M1,M, I1).
loop_entry_1(M,M, _).

loop_entry_0(M0,M, J0, I) :-
   J0 < 5, !,
   M1 is I + J0 + M0,
   J1 is J0 + 1,
   loop_entry_0(M1,M, J1, I).
loop_entry_0(M,M, _, _).