- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在写一个序言程序到 检查变量是否为整数 .
我“返回”结果的方式很奇怪,但我认为这对回答我的问题并不重要。
测试
我已经为这种行为编写了通过单元测试;他们来了...
foo_test.pl
:- begin_tests('foo').
:- consult('foo').
test('that_1_is_recognised_as_int') :-
count_ints(1, 1).
test('that_atom_is_not_recognised_as_int') :-
count_ints(arbitrary, 0).
:- end_tests('foo').
:- run_tests.
count_ints(X, Answer) :-
integer(X),
Answer is 1.
count_ints(X, Answer) :-
\+ integer(X),
Answer is 0.
?- ['foo_test'].
% foo compiled into plunit_foo 0.00 sec, 3 clauses
% PL-Unit: foo
Warning: /home/brandon/projects/sillybin/prolog/foo_test.pl:11:
/home/brandon/projects/sillybin/prolog/foo_test.pl:4:
PL-Unit: Test that_1_is_recognised_as_int: Test succeeded with choicepoint
. done
% All 2 tests passed
% foo_test compiled 0.03 sec, 1,848 clauses
true.
count_ints
谓词合二为一,使用 ;
,但它仍然产生相同的警告。 最佳答案
首先,让我们忘记整个测试框架,只考虑顶层的查询:
?- count_ints(1, 1)。
真的 ;
错误的。
这个交互告诉你,在第一个解决方案之后,一个 选择点离开了。这意味着 替代品 有待尝试,并尝试回溯。在这种情况下,没有其他解决方案,但系统无法在实际尝试之前告知这一点。
使用 all/1
测试用例选项
有多种方法可以修复警告。一个直接的方法是像这样说明测试用例:
test('that_1_is_recognised_as_int', all(Count = [1])) :-
count_ints(1, Count)。
这隐含收集 所有解决方案 ,然后立即对所有这些内容发表声明。
使用 if-then-else
一个更智能的解决方案是使 count_ints/2
本身是确定性的!
一种方法是使用 if-then-else,如下所示:
count_ints(X, 答案) :-
( 整数(X) -> 答案 = 1
;答案 = 0
)。
我们现在有:
?- count_ints(1, 1)。
真的。
即,查询现在确定性地成功。
纯解决方案:清理数据结构
然而 ,最优雅的解决方案是使用 干净的表示 ,以便您和 Prolog 引擎可以通过 区分所有情况模式匹配 .
例如,我们可以 将整数表示为 i(N)
,以及其他所有内容 other(T)
.
在这种情况下,我使用包装器 i/1
和 other/1
来区分情况。
现在我们有:
count_ints(i(_), 1)。
count_ints(其他(_),0)。
测试用例可能如下所示:
测试('that_1_is_recognised_as_int'):-
count_ints(i(1), 1)。
测试('that_atom_is_not_recognised_as_int'):-
count_ints(其他(任意),0)。
这也没有警告地运行,和 具有显着优势,代码实际上可以用于生成 答案:
?- count_ints(Term, Count)。
项 = i(_1900),
计数 = 1 ;
期限 = 其他(_1900),
计数 = 0。
相比之下,我们有其他版本:
?- count_ints(Term, Count)。
计数 = 0。
不幸的是,最多只能考虑覆盖 50% 的可能情况......
更严格的限制
正如鲍里斯在评论中正确指出的那样,我们可以通过 使代码更加严格。约束 i/1
的论据条款到 整数 .例如,我们可以这样写:
count_ints(i(I), 1) :- I inf..sup.
count_ints(其他(_),0)。
现在,论点 必须是 一个整数,它会通过以下查询变得清晰:
?- count_ints(X, 1)。
X = i(_1820),
_1820 inf..sup。
?- count_ints(i(any), 1)。
错误:类型错误:应为“整数”,找到“任何”(原子)
请注意,鲍里斯提到的示例在没有如此严格的约束的情况下也失败了:
?- count_ints(X, 1), X = 任何东西。
错误的。
尽管如此,在参数上添加更多约束通常很有用,如果您需要对整数进行推理,CLP(FD) 约束通常是一个很好的通用解决方案,可以显式声明类型约束,否则这些约束只能隐含在您的程序中。
请注意 integer/1
没有得到备忘录:
?- inf..sup 中的 X,整数(X)。
错误的。
这表明,虽然 X
毫无疑问地限于 整数 在本例中,integer(X)
仍然没有成功。因此,您不能使用像 integer/1
这样的谓词。等作为可靠的检测器类型。依靠模式匹配和使用约束来增加程序的通用性要好得多。
关于unit-testing - 什么是 PL-Unit 中的 "Test succeeded with choicepoint"警告,我该如何解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40711908/
我正在写一个序言程序到 检查变量是否为整数 . 我“返回”结果的方式很奇怪,但我认为这对回答我的问题并不重要。 测试 我已经为这种行为编写了通过单元测试;他们来了... foo_test.pl :-
我是一名优秀的程序员,十分优秀!