Prolog规则可以条件在日期之前,但不能在日期之后,为什么?
Prolog rule can condition to be before a date, but not after a date, why?
我有以下规则在特定日期的数据库中查找事实:
preceding(ID,Date,Category,Preceding) :-
setof([ID,D,Category,Amount], row(ID,D,Category,Amount), Preceding),
D @< Date.
after(ID,After,Category,Rows) :-
setof([ID,D,Category,Amount], row(ID,D,Category,Amount), Rows),
D @> After.
preceding
工作正常:
?- preceding(ID,'2020-01-01',Category,Preceding).
Preceding = [[100002, '2018-11-05', 'CEM', 500.0], [100007, '2018-11-01', 'Consulting Package', 100000.0], [100011, '2017-10-25', 'CEM', 500.0], [100012, '2017-10-15', 'CEM', 500.0], [100012, '2017-10-25', 'Tuition Package', 5543.37], [100013, '2017-10-15', 'CEM'|...], [100013, '2017-11-08'|...], [100014|...], [...|...]|...].
但是after
不起作用:
?- after(ID,'2000-01-01',Category,Rows).
false.
请注意,这两个规则之间的唯一区别 是 @<
与 @>
运算符。我已经尝试改变周围操作数的顺序,并改变规则中语句的顺序,但它不起作用。
我也试过颠倒逻辑:
after(ID,After,Category,Rows) :-
setof([ID,D,Category,Amount], row(ID,D,Category,Amount), Rows),
After @< D.
这也不行。
我什至写了一个单独的规则来检查我是否能让操作员工作:
isafter(A,B) :- A @> B.
这行得通。但是在我的 after
规则中用 isafter(D,After)
替换 D @> After
不起作用。
为什么制作“之前”条件有效,但“之后”条件无效?你能让我的 after
规则生效吗? :)
(我实际上想写一个 between
函数,它同时使用“之前”和“之后”条件,但我意识到我的 between
函数的确切问题是 @>
.)
preceding
works just fine:
是吗?您可以使用不受查询约束的变量 ID
和 Category
来调用它。这已经表明它并不完全符合您的想法。让我们看看里面。
使用这个数据库:
row(100002, '2018-11-05', 'CEM', 500.0).
row(100007, '2018-11-01', 'Consulting Package', 100000.0).
让我们看看您定义中的 setof
目标:
?- setof([ID,D,Category,Amount], row(ID,D,Category,Amount), Preceding).
Preceding = [[100002, '2018-11-05', 'CEM', 500.0], [100007, '2018-11-01', 'Consulting Package', 100000.0]].
Preceding
列表是按我们预期的那样计算的,但是 D
和其他变量呢?他们不受约束。我们可以让它更明确:
?- setof([ID,D,Category,Amount], row(ID,D,Category,Amount), Preceding), write('D: '), writeln(D).
D: _5070
Preceding = [[100002, '2018-11-05', 'CEM', 500.0], [100007, '2018-11-01', 'Consulting Package', 100000.0]].
_5070
形式的东西是 SWI-Prolog 对“未绑定变量”的表示法。所以 D
是 setof
调用之后的一个变量。您是否希望它绑定到 Preceding
列表中的日期之一?哪一个?
所以现在我们可以更接近 @>
与 @<
的问题。您正在做的是将 '2020-01-01'
之类的原子与变量进行比较。 @>
和 @<
实现所谓的“标准术语顺序”。按照这个顺序,变量总是被认为小于原子:
?- SomeVariable @< some_atom.
true.
?- SomeVariable @> some_atom.
false.
这就是为什么您的 @<
总是成功而您的 @>
总是失败的原因。要解决此问题,您需要回过头来重新考虑您希望 setof
调用做什么。
我有以下规则在特定日期的数据库中查找事实:
preceding(ID,Date,Category,Preceding) :-
setof([ID,D,Category,Amount], row(ID,D,Category,Amount), Preceding),
D @< Date.
after(ID,After,Category,Rows) :-
setof([ID,D,Category,Amount], row(ID,D,Category,Amount), Rows),
D @> After.
preceding
工作正常:
?- preceding(ID,'2020-01-01',Category,Preceding).
Preceding = [[100002, '2018-11-05', 'CEM', 500.0], [100007, '2018-11-01', 'Consulting Package', 100000.0], [100011, '2017-10-25', 'CEM', 500.0], [100012, '2017-10-15', 'CEM', 500.0], [100012, '2017-10-25', 'Tuition Package', 5543.37], [100013, '2017-10-15', 'CEM'|...], [100013, '2017-11-08'|...], [100014|...], [...|...]|...].
但是after
不起作用:
?- after(ID,'2000-01-01',Category,Rows).
false.
请注意,这两个规则之间的唯一区别 是 @<
与 @>
运算符。我已经尝试改变周围操作数的顺序,并改变规则中语句的顺序,但它不起作用。
我也试过颠倒逻辑:
after(ID,After,Category,Rows) :-
setof([ID,D,Category,Amount], row(ID,D,Category,Amount), Rows),
After @< D.
这也不行。
我什至写了一个单独的规则来检查我是否能让操作员工作:
isafter(A,B) :- A @> B.
这行得通。但是在我的 after
规则中用 isafter(D,After)
替换 D @> After
不起作用。
为什么制作“之前”条件有效,但“之后”条件无效?你能让我的 after
规则生效吗? :)
(我实际上想写一个 between
函数,它同时使用“之前”和“之后”条件,但我意识到我的 between
函数的确切问题是 @>
.)
preceding
works just fine:
是吗?您可以使用不受查询约束的变量 ID
和 Category
来调用它。这已经表明它并不完全符合您的想法。让我们看看里面。
使用这个数据库:
row(100002, '2018-11-05', 'CEM', 500.0).
row(100007, '2018-11-01', 'Consulting Package', 100000.0).
让我们看看您定义中的 setof
目标:
?- setof([ID,D,Category,Amount], row(ID,D,Category,Amount), Preceding).
Preceding = [[100002, '2018-11-05', 'CEM', 500.0], [100007, '2018-11-01', 'Consulting Package', 100000.0]].
Preceding
列表是按我们预期的那样计算的,但是 D
和其他变量呢?他们不受约束。我们可以让它更明确:
?- setof([ID,D,Category,Amount], row(ID,D,Category,Amount), Preceding), write('D: '), writeln(D).
D: _5070
Preceding = [[100002, '2018-11-05', 'CEM', 500.0], [100007, '2018-11-01', 'Consulting Package', 100000.0]].
_5070
形式的东西是 SWI-Prolog 对“未绑定变量”的表示法。所以 D
是 setof
调用之后的一个变量。您是否希望它绑定到 Preceding
列表中的日期之一?哪一个?
所以现在我们可以更接近 @>
与 @<
的问题。您正在做的是将 '2020-01-01'
之类的原子与变量进行比较。 @>
和 @<
实现所谓的“标准术语顺序”。按照这个顺序,变量总是被认为小于原子:
?- SomeVariable @< some_atom.
true.
?- SomeVariable @> some_atom.
false.
这就是为什么您的 @<
总是成功而您的 @>
总是失败的原因。要解决此问题,您需要回过头来重新考虑您希望 setof
调用做什么。