Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog编程-解决方案的路径方式_Prolog - Fatal编程技术网

Prolog编程-解决方案的路径方式

Prolog编程-解决方案的路径方式,prolog,Prolog,我在大学学习prolog,面临一些问题。我已经发现的只是一个问题的解决方案。然而,我更感兴趣的是思考的方式,即如何获得这样的解决方案 有人能给我一个关于这个领域的建议吗。我非常感谢你的帮助 我举了一个我正在处理的例子,并且在这里找到了一个关于stackoverflow的解决方案,但我要寻找的是他是如何做到这一点的,他是如何找到答案的:) 写一个谓词展平(List,Flat)来展平一个列表,例如展平([a,b,[c,d],[1,2]],foo],X)将给出X=[a,b,c,d,1,2,foo] 这

我在大学学习prolog,面临一些问题。我已经发现的只是一个问题的解决方案。然而,我更感兴趣的是思考的方式,即如何获得这样的解决方案

有人能给我一个关于这个领域的建议吗。我非常感谢你的帮助

我举了一个我正在处理的例子,并且在这里找到了一个关于stackoverflow的解决方案,但我要寻找的是他是如何做到这一点的,他是如何找到答案的:)

写一个谓词展平(List,Flat)来展平一个列表,例如展平([a,b,[c,d],[1,2]],foo],X)将给出X=[a,b,c,d,1,2,foo]

这是我在stackoverflow上找到的答案:

flatten(List, Flattened):-
   flatten(List, [], Flattened).

flatten([], Flattened, Flattened).
flatten([Item|Tail], L, Flattened):-
  flatten(Item, L1, Flattened),
  flatten(Tail, L, L1).
flatten(Item, Flattened, [Item|Flattened]):-
  \+ is_list(Item).
这个答案属于用户gusbro,由用户Parhs询问,我试图找到一种方法联系用户gusbro,询问他如何得出这样的答案,但我不能


非常感谢。

好吧,我只能说解决问题的方法很大程度上取决于问题本身。有一组问题可以使用Prolog来解决,Prolog非常适合解决这些问题

在这类问题中,一个人可以通过将一个更大的问题划分为两个或多个案例类来推导其解决方案

在一个类中,我们有“基本情况”,当输入不能进一步划分为更小的情况时,我们提供问题的解决方案

另一类是“递归案例”,我们将输入分成几个部分,分别求解,然后将结果“连接”起来,为这个较大的输入提供解决方案

在Flatte/2的示例中,我们希望将项目列表作为输入,其中每个项目也可能是一个列表,结果应该是一个包含输入中所有项目的列表。因此,我们将问题分为几个部分。 我们将使用一个辅助参数来保存中间的展平列表,这就是我们实现展平/3的原因

因此,我们的展平/2谓词将使用空列表作为起始中间展平列表来调用展平/3:

flatten(List, Flattened):-
   flatten(List, [], Flattened).
现在对于flatte/3谓词,我们有两个基本情况。第一个是空列表。请注意,当输入为空列表时,我们无法进一步划分问题。在本例中,我们只取中间的展平列表作为结果

flatten([], Flattened, Flattened).
我们现在采取递归步骤。这涉及到获取输入列表并将问题分为两个步骤。第一步是展平此输入列表的第一项。第二步是递归展平其余部分:

flatten([Item|Tail], L, Flattened):-
  flatten(Item, L1, Flattened),
  flatten(Tail, L, L1).
好的,调用展平(Item,L1,flatted)展平第一个项,但将未绑定变量L1作为中间列表传递。这只是一个诡计,因此在返回谓词时,变量L1仍然是无界的,并且平坦的形式为[…|L1],其中。。。是项的扁平项

下一步调用展平(Tail,L,L1)展平输入列表的其余部分,结果以L1为界

我们的最后一个子句实际上是另一个基本情况,它处理单个项目(不是列表)。因此,我们有:

flatten(Item, Flattened, [Item|Flattened]):-
  \+ is_list(Item).

它检查项是否是列表,当它不是列表时,它将结果绑定为一个head=item的列表,并作为中间平坦列表的尾部。

好吧,我所能说的是,解决问题的方法在很大程度上取决于问题本身。有一组问题可以使用Prolog来解决,Prolog非常适合解决这些问题

在这类问题中,一个人可以通过将一个更大的问题划分为两个或多个案例类来推导其解决方案

在一个类中,我们有“基本情况”,当输入不能进一步划分为更小的情况时,我们提供问题的解决方案

另一类是“递归案例”,我们将输入分成几个部分,分别求解,然后将结果“连接”起来,为这个较大的输入提供解决方案

在Flatte/2的示例中,我们希望将项目列表作为输入,其中每个项目也可能是一个列表,结果应该是一个包含输入中所有项目的列表。因此,我们将问题分为几个部分。 我们将使用一个辅助参数来保存中间的展平列表,这就是我们实现展平/3的原因

因此,我们的展平/2谓词将使用空列表作为起始中间展平列表来调用展平/3:

flatten(List, Flattened):-
   flatten(List, [], Flattened).
现在对于flatte/3谓词,我们有两个基本情况。第一个是空列表。请注意,当输入为空列表时,我们无法进一步划分问题。在本例中,我们只取中间的展平列表作为结果

flatten([], Flattened, Flattened).
我们现在采取递归步骤。这涉及到获取输入列表并将问题分为两个步骤。第一步是展平此输入列表的第一项。第二步是递归展平其余部分:

flatten([Item|Tail], L, Flattened):-
  flatten(Item, L1, Flattened),
  flatten(Tail, L, L1).
好的,调用展平(Item,L1,flatted)展平第一个项,但将未绑定变量L1作为中间列表传递。这只是一个诡计,因此在返回谓词时,变量L1仍然是无界的,并且平坦的形式为[…|L1],其中。。。是项的扁平项

下一步调用展平(Tail,L,L1)展平输入列表的其余部分,结果以L1为界

我们的最后一个子句实际上是另一个基本情况,它处理单个项目(不是列表)。因此,我们有:

flatten(Item, Flattened, [Item|Flattened]):-
  \+ is_list(Item).

它检查项是否是列表,当它不是列表时,它将结果绑定为一个列表,head=item,tail为中间的扁平列表。

首先,我将向您展示我解决问题的方法,然后我有一些学习递归思考的资源

下面是我对“展平列表(列表…)列表”问题的解决方案。我对它进行了注释,以显示我是如何到达那里的:

  • 首先,让我们定义
    flatten-head( X , [X] ).
    
    flatten ( X , R ) :-
      flatten ( X , [] , R )
      .
    
    flatten( [] , X , X ) .
    flatten( [X|Xs] , T , Y ) :-
      flatten_head(X,X1)      ,
      append( T,X1,T1)        ,
      flatten( Xs , T1 , Y )
      .
    
    flatten-head( X , Y   ) :-
      nonvar(X)             ,
      flatten( X , Y )
      .
    flatten-head( X , [X] ) .