我的教授将此作为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) 创建二维数组:
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,但我仍然想知道为什么这是正确的类型。