小编Bar*_*ers的帖子

以声明方式解决河内塔(Prolog)

我的教授将此作为Prolog的一个例子.这是一个解决河内之塔拼图的程序,你必须将一堆磁盘移动到另一个挂钩,方法是将一个磁盘移动到另一个磁盘上,而不是在较小的磁盘上放置一个更大的磁盘.

现在,我不喜欢那个节目.我被告知Prolog是用于声明性编程的.我不想编程如何解决问题,我想用Prolog写下问题什么.然后让Prolog解决它.

到目前为止我的努力可以在下面找到.有两种类型的我使用列表,一个行动顺序是这样表示:[[1,2],[3,1]]; 这将是"将顶部磁盘从挂钉1移动到挂钉2,将磁盘从挂钉3移动到挂钉1".我的第二种类型的列表是一个状态,例如,如果有三个挂钩[[1,2,3], [], []]意味着第一个挂钩上有三个磁盘.较小的磁盘具有较小的数字,因此内部列表的前面是堆栈的顶部.

% A sequence of actions (first argument) is a solution if it leads
% from the begin state (second argument) to the End state (third argument).

solution([], X, X).

solution([[FromIdx | ToIdx] | T], Begin, End) :-
    moved(FromIdx, ToIdx, Begin, X),
    solution(T, X, End).

% moved is true when Result is the resulting state after moving
% a disk from FromIdx to …
Run Code Online (Sandbox Code Playgroud)

declarative prolog towers-of-hanoi dcg clpfd

7
推荐指数
1
解决办法
1006
查看次数

Haskell 和 Data.Array.//:为什么这种类型是正确的?

创建二维数组:

import Data.Array
arr = listArray ((1, 1), (10, 10)) [1..]  -- :: (Ix i, Num i, Num e, Enum e) => Array i e
Run Code Online (Sandbox Code Playgroud)

//可用于更新值。您需要提供带有索引和值的元组列表。由于我们的索引是一个二元组,因此类型需要是[((a, b), e)].

 arr // _  -- _ :: [((a, b), e)]
Run Code Online (Sandbox Code Playgroud)

现在我[(1, 999)]偶然使用了更新第一个值。当然应该是[((1,1), 999)]。然而,这个错误竟然是类型正确的!

 arr2 = arr // [(1, 999)]
 arr2  -- :: (Ix a, Ix b, Enum e, Num a, Num b, Num e, Num (a, b)) => Array (a, b) e
Run Code Online (Sandbox Code Playgroud)

当我尝试评估时它挂起arr2,但我仍然想知道为什么这是正确的类型。

haskell

3
推荐指数
2
解决办法
104
查看次数

标签 统计

clpfd ×1

dcg ×1

declarative ×1

haskell ×1

prolog ×1

towers-of-hanoi ×1