Prolog - 递归地将数字附加到列表中 [英] Prolog - Recursively append numbers to a list

查看:47
本文介绍了Prolog - 递归地将数字附加到列表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始学习 Prolog,并且在递归概念上遇到了麻烦.现在,仅出于练习的目的,我正在尝试编写一个程序,将 10 个数字附加到一个列表中,然后打印出该列表.

I am just starting to learn Prolog, and I am having troubles wrapping my head around recursive concepts. Right now, solely for the purpose of practice, I am trying to write a program that appends 10 numbers to a list and then prints out that list.

这个程序的自我强加规则是必须在主谓词中声明"列表(我不确定这是否是 Prolog 的正确词),它调用另一个谓词将数字附加到列表.

The self-imposed rule for this program is that the list has to be 'declared' (I am not sure if that is the correct word for Prolog) in a main predicate, which calls another predicate to append numbers to the list.

到目前为止,这是我所拥有的,我知道它不起作用,因为我试图在 addToList 谓词的末尾重新定义 List,即语言中不允许.

This is what I have so far, and I know it won't work because I am trying to redefine List at the end of the addToList predicate, which is not allowed in the language.

% Entry point that declares a list (`List`) to store the 10 numbers
printList(List) :-
    addToList(0, List),
    writeln(List).

% Base case - once we hit 11 we can stop adding numbers to the list
addToList(11, _).

% First case - this predicate makes adding the first number easier for me...
addToList(0, List) :-
    append([], [0], NewList),
    addToList(1, NewList),
    append([],  NewList, List). % This is valid, but List will just be [0] I think..

% Cases 1-10
addToList(Value, List) :-
    append(List, [Value], NewList),
    NextVal is Value+1,
    addToList(NextVal, NewList),
    append([], NewList, List). % This is INVALID since List is already defined

这个程序将开始于:

printList(List).

是否有一种简单的方法可以更改我编写的损坏程序以使其正常工作?我对如何获取存储在 List 中的数字非常迷茫.

Is there a simple way to change up the broken program I have written up to make it work correctly? I am super lost on how to get the numbers stored in List.

推荐答案

您正在按程序进行思考,在 prolog 中您不能更改变量.您正在尝试自己构建列表.在 prolog 样式中,您尝试声明所需列表的约束.如果 nlist/2 是一个给出 N 个数字列表的谓词,那么它的属性究竟是什么?nlist(0, []). 如果 nlist(N, Xs) 然后 nlist(N+1, [N+1 | Xs]).所以你只需要写这些,让 prolog 来负责构建.

You are thinking procedurally, in prolog you cannot change variables. You are trying to construct the list yourself. In prolog-style you try to declare the constraints of the list you want. If nlist/2 is a predicate that gives a list of N numbers then what exactly are it's properties? nlist(0, []). and if nlist(N, Xs) then nlist(N+1, [N+1 | Xs]). So you just write these and let prolog take care of the construction.

nlist(0, []).
nlist(N, [N | Xs]) :-
    N>0, N1 is N-1,
    nlist(N1, Xs).

如果您对递归调用的发生方式感到困惑,请尝试使用 trace/0trace/1.您可以在以下跟踪中看到调用是如何完成的.您可以通过调用 trace(nlist) 获得此信息.

If you are confused how the recursion calls are taking place, try using trace/0 or trace/1. You can see how the calls are being done in the following trace. You can get this by calling trace(nlist).

?- nlist(3, X).
 T Call: nlist(3, _78)
 T Call: nlist(2, _902)
 T Call: nlist(1, _1464)
 T Call: nlist(0, _2026)
 T Exit: nlist(0, [])
 T Exit: nlist(1, [1])
 T Exit: nlist(2, [2, 1])
 T Exit: nlist(3, [3, 2, 1])
X = [3, 2, 1]

比较程序化的代码如下

addToList(11, A, A).

% Cases 1-10
addToList(Value, List, NewList) :-
    Value < 11,  append(List, [Value], Temp),
    NextVal is Value+1,
    addToList(NextVal, Temp, NewList).

这给出了中间参数是累加器.当您达到 11 时,累加器就是答案.

This gives the middle parameter is the accumulator. When you reach 11 the accumulator is the answer.

?- addToList(1, [], X).
X = [1, 2, 3, 4, 5, 6, 7, 8, 9|...] 

?- addToList(5, [], X).
X = [5, 6, 7, 8, 9, 10] 

nlistaddToList 中查看示例跟踪以及它们之间的区别.尝试找出差异及其发生的原因.

Look at the sample trace and the difference between them in nlist and addToList. Try to figure out the differences and why the are happening.

?- addToList(7, [], X).
 T Call: addToList(7, [], _33565254)
 T Call: addToList(8, [7], _33565254)
 T Call: addToList(9, [7, 8], _33565254)
 T Call: addToList(10, [7, 8, 9], _33565254)
 T Call: addToList(11, [7, 8, 9, 10], _33565254)
 T Exit: addToList(11, [7, 8, 9, 10], [7, 8, 9, 10])
 T Exit: addToList(10, [7, 8, 9], [7, 8, 9, 10])
 T Exit: addToList(9, [7, 8], [7, 8, 9, 10])
 T Exit: addToList(8, [7], [7, 8, 9, 10])
 T Exit: addToList(7, [], [7, 8, 9, 10])
X = [7, 8, 9, 10] 

这篇关于Prolog - 递归地将数字附加到列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆