Prolog,从一个区间开始计数; (SWI-PROLOG)

发布于 2024-09-28 02:50:21 字数 358 浏览 14 评论 0原文

我有一个小问题。我需要创建一个从自然数到其他自然数的谓词。我也必须进行检查,确保第二个间隔大于第一个间隔。然而我在路上被困住了。

这是我的代码(SWI-PROLOG)

count(O, _, O).
count(A, B, C) :- count(A, B, D), C is D+1, C =< B.

它工作得很好,如果我输入 我可以获得结果 C=1, C=2, C=3, C=4 count(1, 4, C). 但是我在最后卡住了,这会导致堆栈溢出错误。

问题是我该如何让它停下来?我几乎尝试了一切。 =(

谢谢您的回复!

I have a small question. I need to make a predicate that counts from a natural number to some other natural number. I have to implement a check too, that the second interval is bigger than the first one. However I got stuck during my way.

Here is my code (SWI-PROLOG)

count(O, _, O).
count(A, B, C) :- count(A, B, D), C is D+1, C =< B.

It works kind of well as, I can get the results C=1, C=2, C=3, C=4 if I type in count(1, 4, C). However I get stuck at the end, it will result in an error with stack overflow.

The question is how do I make it to stop? I have tried almost everything. =(

Thanks for your response!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你的笑 2024-10-05 02:50:21

SWI-Prolog 有一个内置功能...

?- help(between).
between(+Low, +High, ?Value)
    Low  and High are  integers, High >=Low.   If  Value is an  integer,
    Low=< Value=< High.   When Value  is a  variable it is  successively
    bound  to  all integers  between  Low and  High.    If High  is  inf
    or  infinite between/3 is  true iff Value>= Low,  a feature that  is
    particularly  interesting  for generating  integers from  a  certain
    value.

true.

?- between(1, 4, Value).
Value = 1 ;
Value = 2 ;
Value = 3 ;
Value = 4.

?- 

SWI-Prolog has a builtin for that...

?- help(between).
between(+Low, +High, ?Value)
    Low  and High are  integers, High >=Low.   If  Value is an  integer,
    Low=< Value=< High.   When Value  is a  variable it is  successively
    bound  to  all integers  between  Low and  High.    If High  is  inf
    or  infinite between/3 is  true iff Value>= Low,  a feature that  is
    particularly  interesting  for generating  integers from  a  certain
    value.

true.

?- between(1, 4, Value).
Value = 1 ;
Value = 2 ;
Value = 3 ;
Value = 4.

?- 
养猫人 2024-10-05 02:50:21

正如 Paulo Moura 指出的那样,重新排序将解决部分问题。让它优雅地终止,可以通过添加一个附加子句来处理递归终止条件来实现。

试试这个。

countAtoB(A,B,A) :-
    A =:= B, !.

countAtoB(A,B,A) :-
    A < B.

countAtoB(A,B,I) :- 
    A < B, 
    X is A+1,  
    countAtoB(X,B,I).

查询将如下所示。为了进行比较,我使用 Between/3 重复了同一组测试查询,之后海峡。

?- countAtoB(1,4,I).
I = 1 ;
I = 2 ;
I = 3 ;
I = 4.

?- countAtoB(4,4,I).
I = 4.

?- countAtoB(4,1,I).
false.

?- countAtoB(4,1,1000).
false.

?- between(1,4,I).
I = 1 ;
I = 2 ;
I = 3 ;
I = 4.

?- between(4,4,I).
I = 4.

?- between(4,1,I).
false.

?- between(4,1,1000).
false.

?-

As Paulo Moura pointed out, re-ordering will solve part of the problem. Getting it to terminate gracefully, may be achieved by adding an additional clause to handle the recursive terminating condition.

Try this.

countAtoB(A,B,A) :-
    A =:= B, !.

countAtoB(A,B,A) :-
    A < B.

countAtoB(A,B,I) :- 
    A < B, 
    X is A+1,  
    countAtoB(X,B,I).

Queries would then look like this. For the sake of comparison, I have repeated the same set of test queries using between/3, strait after.

?- countAtoB(1,4,I).
I = 1 ;
I = 2 ;
I = 3 ;
I = 4.

?- countAtoB(4,4,I).
I = 4.

?- countAtoB(4,1,I).
false.

?- countAtoB(4,1,1000).
false.

?- between(1,4,I).
I = 1 ;
I = 2 ;
I = 3 ;
I = 4.

?- between(4,4,I).
I = 4.

?- between(4,1,I).
false.

?- between(4,1,1000).
false.

?-
享受孤独 2024-10-05 02:50:21

count(A, B, C) :- count(A, B, D), ...

会导致无限递归。

只需重新排序谓词,如下所示:

count(A, B, A) :- A =< B.
count(A, B, C) :- A < B, A2 is A+1, count(A2, B, C).

This

count(A, B, C) :- count(A, B, D), ...

causes an infinite recursion.

Just reorder the predicate, like this:

count(A, B, A) :- A =< B.
count(A, B, C) :- A < B, A2 is A+1, count(A2, B, C).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文