Prolog:判断给定整数是否为 2 的幂并且可用作生成器的谓词
Prolog: Predicate that tells if given integer is a power of two and is usable as a generator
我想要一个谓词 isPowTwo/1
,它对 2 的每一次幂都成立。这是我的方法:
isPowTwo(N) :- N > 0, N is N /\ (-N).
它工作得很好,如果我给它整数:
?- isPowTwo(2).
true.
?- isPowTwo(4).
true.
?- isPowTwo(6).
false.
但是当我想要它作为发电机使用时它不起作用:
?- isPowTwo(N).
ERROR: >/2: Arguments are not sufficiently instantiated
我如何编写一个谓词,以升序生成 2 的幂?
编辑:重要的是使用普通整数而不是 Peano 数。
经验法则
Are you reasoning over integers? → Use your Prolog system's CLP(FD) constraints.
示例解决方案
power_of_two(N) :-
N #> 0,
N #= 2^_.
示例查询和答案
具体整数
?- power_of_two(2).
true.
?- power_of_two(4).
true.
?- power_of_two(6).
false.
最一般的查询
?- power_of_two(N).
N in 1..sup,
2^_G844#=N.
枚举
?- power_of_two(N), length(_, N).
N = 1 ;
N = 2 ;
N = 4 ;
N = 8 ;
N = 16 ;
N = 32 ;
etc.
结论
使用正常 整数,不使用 Peano 数。
约束允许我们以纯粹、一般和简洁的方式陈述解决方案。
我发现另一种方法作为生成器效果很好(比使用 length(_, N)
作为目标的 CLP(FD) 版本更快),不使用 clpfd
,但往往以无限结束-loop 如果用作验证者:
isPowTwo(1).
isPowTwo(N) :- isPowTwo(N1), N is N1 * 2.
查看其行为:
?- isPowTwo(N).
N = 1 ;
N = 2 ;
N = 4 ;
N = 8 ;
N = 16 ;
N = 32 ;
N = 64 ;
N = 128 ;
N = 256 ;
N = 512 ;
N = 1024 ;
...
?- isPowTwo(4).
true ;
... (infinite loop)
?- isPowTwo(3).
... (infinite loop)
我想要一个谓词 isPowTwo/1
,它对 2 的每一次幂都成立。这是我的方法:
isPowTwo(N) :- N > 0, N is N /\ (-N).
它工作得很好,如果我给它整数:
?- isPowTwo(2).
true.
?- isPowTwo(4).
true.
?- isPowTwo(6).
false.
但是当我想要它作为发电机使用时它不起作用:
?- isPowTwo(N).
ERROR: >/2: Arguments are not sufficiently instantiated
我如何编写一个谓词,以升序生成 2 的幂?
编辑:重要的是使用普通整数而不是 Peano 数。
经验法则
Are you reasoning over integers? → Use your Prolog system's CLP(FD) constraints.
示例解决方案
power_of_two(N) :- N #> 0, N #= 2^_.
示例查询和答案
具体整数
?- power_of_two(2). true. ?- power_of_two(4). true. ?- power_of_two(6). false.
最一般的查询
?- power_of_two(N). N in 1..sup, 2^_G844#=N.
枚举
?- power_of_two(N), length(_, N). N = 1 ; N = 2 ; N = 4 ; N = 8 ; N = 16 ; N = 32 ; etc.
结论
使用正常 整数,不使用 Peano 数。
约束允许我们以纯粹、一般和简洁的方式陈述解决方案。
我发现另一种方法作为生成器效果很好(比使用 length(_, N)
作为目标的 CLP(FD) 版本更快),不使用 clpfd
,但往往以无限结束-loop 如果用作验证者:
isPowTwo(1).
isPowTwo(N) :- isPowTwo(N1), N is N1 * 2.
查看其行为:
?- isPowTwo(N).
N = 1 ;
N = 2 ;
N = 4 ;
N = 8 ;
N = 16 ;
N = 32 ;
N = 64 ;
N = 128 ;
N = 256 ;
N = 512 ;
N = 1024 ;
...
?- isPowTwo(4).
true ;
... (infinite loop)
?- isPowTwo(3).
... (infinite loop)