在 Prolog 中生成整数的最佳方法 [英] Best way to generate integer numbers in Prolog

查看:45
本文介绍了在 Prolog 中生成整数的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想生成整数,我正在寻找最好的方法来做到这一点.示例:

I want to generate integer numbers and I'm looking for the best way to do this. Example:

?- number2(N).
N = 0;
N = 1;
N = 2;
...
(and so on)

现在我只是使用length/2:

number2(N) :- length(_, N).

但我认为应该有更好的方法(不创建临时列表).我可能可以根据 length/2 的代码自己编写一些代码,但我正在寻找使用现有内置谓词的解决方案.有没有比 length/2 更好的内置谓词?我找不到类似的东西.

But I think that there should be some better way (without creating temporary list). I could probably write some code myself basing on code of length/2 but I'm looking for solution that employs already existing, built-in predicates. Is there any built-in predicate that would work better than length/2? I couldn't find anything like that.

推荐答案

你的解决方案很难超越;可能不值得付出努力.毕竟,现在有三种建议对于一种或另一种情况都是不正确的:

It is hard to top your solution ; and probably it is not worth the effort. After all, there are now three suggestions that all are incorrect for one case or another:

?- time( (number2_gk(N), N == 10000) ). % your original
% 20,002 inferences, 0.007 CPU in 0.007 seconds (99% CPU, 3006132 Lips)
N = 10000 

?- time( (number2_cc(N), N == 10000) ). % quadratic overhead
% 50,025,001 inferences, 28.073 CPU in 28.196 seconds (100% CPU, 1781945 Lips)
N = 10000 

?- time( (next_integer(N), N == 10000) ).
% 20,002 inferences, 0.011 CPU in 0.011 seconds (100% CPU, 1822247 Lips)
N = 10000 

然而,number2_cc(-1)next_integer(-1) 只是循环,length/2 实际上应该产生域错误,就像 SICStus 和许多其他系统一样.

However, number2_cc(-1) and next_integer(-1) simply loop, length/2 actually should produce a domain error, like SICStus and many other systems do.

如您所见,CC 的解决方案比您原来的解决方案更糟糕.

As you can see, CC's solution is worse than your original one.

在以下情况下,mat 的建议也会产生不同的行为:

Also the suggestion by mat produces different behavior in the following situation:

goal_expansion(length(Ls,L), between(0,infinite,L)) :-
   var_property(Ls, fresh(true)).

as(N) :-
   length(L,N),
   phrase(a, L).

a --> [a], a.
a --> [].

目标 as(N) 现在循环而不是枚举所有 N.

The goal as(N) now loops instead of enumerating all N.

如果您真的坚持要改进,请考虑以下使用 library(clpfd) 的尾递归解决方案:

If you really insist on an improvement, consider the following tail-recursive solution using library(clpfd):

nat(N) :-
   nat(N, 0).

nat(N, N0) :-
  N #>= N0,
  (  N = N0
  ;  N1 is N0+1,
     nat(N, N1)
  ).

?- time( (nat(N), N == 10000) ).
% 1,850,152 inferences, 0.544 CPU in 0.545 seconds (100% CPU, 3399793 Lips)

这只是对如下查询的改进.否则只会浪费资源.

Which is only an improvement for queries like the following. Otherwise it is just a waste of resources.

?- N in 1..2, nat(N).

这篇关于在 Prolog 中生成整数的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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