Prolog 中的全局堆栈错误
我正在尝试在 Prolog 中运行以下程序。
mama_mia1(A,M,LI,HI,LO,HO,AA) :-
p1(A,M,LI,HI,LO,HO,PROGS),
reverse(PROGS,PROG),
atom_chars(AA,PROG),
!.
p1(_,_,LO,LO,LO,_,[]).
p1(_,_,HO,HO,_,HO,[]).
p1(_,_,LO,HO,LO,HO,[]).
p1(_,_,X,LO,LO,HO,[]) :- X>LO,X<HO.
p1(_,_,X,HO,LO,HO,[]) :- X>LO,X<HO.
p1(_,_,LO,Y,LO,HO,[]) :- Y>LO,Y<HO.
p1(_,_,HO,Y,LO,HO,[]) :- Y>LO,Y<HO.
p1(_,_,X,Y,LO,HO,[]) :- X>LO,X<HO,Y>LO,Y<HO.
p1(A,M,X,Y,LO,HO,PROG) :-
( (X1 is X+A, H1 is HO+1, X1<H1, Y1 is Y+A, Y1<H1 )
-> append(PROG1,['A'],PROG),
p1(A,M,X1,Y1,LO,HO,PROG1)
; false).
p1(A,M,X,Y,LO,HO,PROG) :-
( (X2 is X * M, H1 is HO+1, X2<H1, Y2 is Y * M, Y2<H1)
-> append(PROG2,['M'],PROG),
p1(A,M,X2,Y2,LO,HO,PROG2)
; false).
该程序应计算从 li 和 hi 之间的每个数字到 lo 和 ho 之间的结果的适当的加法和乘法路径。加法对应于字母 A,乘法对应于 M。在程序结束时,我们应该得到与我们找到的路径相对应的 As 和 Ms 字符串。
该程序运行良好,但在尝试测试用例时:
mama_mia1(70000,17,2,5,89000,89900,P)
我收到一条“错误:超出全局堆栈”消息。
任何想法代码有什么问题吗?
I am trying to run the following program in Prolog.
mama_mia1(A,M,LI,HI,LO,HO,AA) :-
p1(A,M,LI,HI,LO,HO,PROGS),
reverse(PROGS,PROG),
atom_chars(AA,PROG),
!.
p1(_,_,LO,LO,LO,_,[]).
p1(_,_,HO,HO,_,HO,[]).
p1(_,_,LO,HO,LO,HO,[]).
p1(_,_,X,LO,LO,HO,[]) :- X>LO,X<HO.
p1(_,_,X,HO,LO,HO,[]) :- X>LO,X<HO.
p1(_,_,LO,Y,LO,HO,[]) :- Y>LO,Y<HO.
p1(_,_,HO,Y,LO,HO,[]) :- Y>LO,Y<HO.
p1(_,_,X,Y,LO,HO,[]) :- X>LO,X<HO,Y>LO,Y<HO.
p1(A,M,X,Y,LO,HO,PROG) :-
( (X1 is X+A, H1 is HO+1, X1<H1, Y1 is Y+A, Y1<H1 )
-> append(PROG1,['A'],PROG),
p1(A,M,X1,Y1,LO,HO,PROG1)
; false).
p1(A,M,X,Y,LO,HO,PROG) :-
( (X2 is X * M, H1 is HO+1, X2<H1, Y2 is Y * M, Y2<H1)
-> append(PROG2,['M'],PROG),
p1(A,M,X2,Y2,LO,HO,PROG2)
; false).
The program should calculate an appropriate path of additions and multiplications leading from every number between li and hi to a result between lo and ho. An addition corresponds to the letter A and multiplication corresponds to M. At the end of the program we are supposed to get a string of As and Ms corresponding to the path we found.
The program runs well but when trying the test case :
mama_mia1(70000,17,2,5,89000,89900,P)
I get an "ERROR: out of global stack " message.
Any ideas what is wrong with the code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
真的吗?让我们尝试一个最小的情况:
也就是说,即使在这种非常简单的情况下,您的程序也会循环。然而,却偏偏找到了两个答案!第二个答案使用
library(double_quotes)
来打印"A"
代替['A']
。在 Prolog 中,你不会只得到一个答案,你可能会得到几个答案...
直接检测此类非终止问题的一种简单方法是添加一个目标
false
对于您的查询:我们可以在您的计划中添加更多此类目标
false
。严格来说,只有当您的程序是纯粹的、单调的程序时,这才有可能。您正在使用 cut 和 if-then-else,它们在一般情况下都会破坏此类属性。但是,就您而言,它们可以在以下 failure-slice考虑这个目标
append(PROG1,['A'],PROG)
。变量PROG1
在这里第一次出现,因此它从未被实例化。此外,PROG
未实例化。因此这个目标将会循环。将
append(PROG1,['A'],PROG)
替换为PROG = ['A'|PROG1]
。现在元素以相反的方向出现,因此不需要反转。查询
mama_mia1(70000,17,2,5,89000,89900,P)
现在就像false
一样失败。Really? Let's try out a minimal case:
That is, even in this very simple case your program loops. However, it happened to find two answers! The second answer uses
library(double_quotes)
for printing"A"
in place of['A']
.In Prolog you do not get just one answer, you may get several of them...
An easy way to directly detect such problems of non-termination is to add a goal
false
to your query:We can add further such goals
false
into your program. Strictly speaking, this is only possible if your program is a pure, monotonic one. You are using cut and if-then-else which both destroy such properties in the general case. However, in your case, they can just be discarded in the following failure-sliceConsider this goal
append(PROG1,['A'],PROG)
. The variablePROG1
occurs here for the first time and thus it is never instantiated. AlsoPROG
is not instantiated. And thus this goal will loop.Replace
append(PROG1,['A'],PROG)
byPROG = ['A'|PROG1]
. Now the elements occur in opposite direction and thus no reversing is needed.The query
mama_mia1(70000,17,2,5,89000,89900,P)
now simply fails just likefalse
did.这
消息意味着您的程序需要更多内存。要么它陷入某个消耗所有内存的无限循环,要么它没有任何问题,只是输入太大,因此需要更多内存。
考虑到您的输入看起来相当大,并假设您测试了较小的输入并且没有发生问题,我想说您只需要更多内存
您可以扩展 堆栈 或者您可以尝试使用更少的内存。
当然,如果这是提交到某个地方进行检查的某种练习,那么您可以获得的内存可能会受到限制:b
The
message means that your program needs more memory. Either it's stuck in some infinite loop that consumes all the memory or there is nothing wrong with it and the input is just too large so it needs more memory.
Considering that your input looks quite large and assuming that you have tested smaller inputs and no problem occurred I would say that you just need more memory
You can expand the size of the stack OR you can try to use less memory.
Of course, if this is some sort of exercise submitted somewhere to be checked, there could be limits in how much memory you could get :b