prolog - 使用序言中的列表打印出动态大小的真值表
问题描述
在给定 2 个前提和 3 个谓词和一个结论的情况下,我创建了一个table
用于创建真值表的子句:
bool(true).
bool(false).
% Function for printing out the table
table(P,Q,R,E1,E2,Conclusion):-
write('P\tQ\tR\t'),
write(E1), write('\t'),
write(E2), write('\t'),
write(Conclusion),
write('\tCheck'), nl,
printValues(P,Q,R,E1,E2,Conclusion).
% Function prints out the truth tables.
printValues(P,Q,R,E1,E2,Conclusion):-
bool(P), bool(Q), bool(R), % Get the permutations of all the possible combinations of true and false.
write(P), format(P), write('\t'), % Print each true/false.
write(Q), format(Q), write('\t'),
write(R), format(R), write('\t'),
writePremise(E1), write('\t'), % Evaluate the premises and write out the result.
writePremise(E2), write('\t\t'),
writePremise(Conclusion), write('\t\t'), % Evaluate the conclusion and write out the result.
writeCheck(E1, E2, Conclusion). % perform check to see if valid.
% Evalutes a given premise and writes out true or false.
writePremise(E):-
(E -> write('true'); write('false')).
writeCheck(E1, E2, Conclusion):-
((E1,E2 -> (Conclusion -> write('okay'); write('invalid')));
write('okay')), nl, fail.
给定这样的查询会创建一个真值表:
| ?- table(P,Q,R,and(P,Q),P,my_not(Q)).
P Q R and(_26,_27) _26 my_not(_27) Check
true true true true true false invalid
true true false true true false invalid
true false true false true true okay
true false false false true true okay
false true true false false false okay
false true false false false false okay
false false true false false true okay
false false false false false true okay
no
现在我想更改创建一个可以包含两个列表的新子句 - 一个用于谓词,一个用于前提。
它目前看起来像这样:
tableMoreDynamic(Predicates,Premises, Conclusion):-
writePredicates(Predicates),
writePremises(Premises),
writePremise(Conclusion), write('\t\t'),
writeDynamicCheck(Premises, Conclusion),
nl, fail.
writePredicates([]):- true.
writePredicates([HEAD|TAIL]):-
bool(HEAD),
write(HEAD) , write('\t'),
writePredicates(TAIL).
writePremises([]):- true.
writePremises([HEAD|TAIL]):-
writePremise(HEAD), write('\t'),
writePremises(TAIL).
writeDynamicCheck(Premises, Conclusion):-
(checkList(Premises) -> (Conclusion -> write('okay'); write('invalid'));
write('okay')).
checkList([]):- true.
checkList([HEAD|TAIL]):-
HEAD,
checkList(TAIL).
它目前的工作原理是打印出前提、结论和有效检查的正确值。然而,由于 writePredicates 子句中的回溯,它不会在每一行打印出所有不同的谓词:
| ?- tableMoreDynamic([P,Q],[P],my_not(P)).
true true true false invalid
false true false invalid
false true false true okay
false false true okay
因此,我想知道是否有办法知道您是否在此函数中回溯(以便我们可以重新打印该行上的早期值)。或者也许是一种将 bool 子句映射到列表的方法,这样我们就可以打印出该列表。为代码墙道歉。谢谢
解决方案
因此,我想知道是否有办法知道您是否在此函数中回溯(以便我们可以重新打印该行上的早期值)。
可能有一些巧妙的技巧可以做到这一点,但对于对问题的令人困惑的解释来说,这将是一个非常令人困惑的解决方案。问题本身很简单:
或者也许是一种将 bool 子句映射到列表的方法,这样我们就可以打印出该列表。
是的。而且您已经知道该怎么做,因为writePredicates
无论如何这就是您在里面做的事情!您唯一缺少的是,您应该在开始打印之前对完整的布尔列表进行“标记”,而不是交错标记和打印单个元素。
所以你只需要这样:
bools([]).
bools([Bool | Bools]) :-
bool(Bool),
bools(Bools).
tableMoreDynamic(Predicates,Premises, Conclusion):-
bools(Predicates),
writePredicates(Predicates),
...
保持其余代码不变。(你可以删除bool
里面的调用writePredicates
,它不再做任何事情。)
这将打印完整的表格:
?- tableMoreDynamic([P,Q],[P],my_not(P)).
true true true false invalid
true false true false invalid
false true false true okay
false false false true okay
false.
如果您不想自己写出整个递归bools
,如果您的 Prolog 提供了一些高阶谓词,则可能会有更短的解决方案。例如,在 SWI-Prolog 中,您可以调用:
maplist(bool, Predicates)
根本不需要定义bools
谓词。
推荐阅读
- typescript - Vue 3 - 子组件的双向数据绑定没有问题
- random-forest - 在随机森林中遇到一棵只包含标签的树怎么办?
- kubernetes-helm - 如何覆盖 Helm Chart 中的表/映射
- amazon-web-services - 命名 AWS EC2 安全组 IP 权限规则
- accessibility - WCAG 标准中是否有“测验”的例外情况?
- unicode - Google 字体中无法访问的字形和符号
- python - 为什么使用 pyautogui 点击时会有这样的延迟?
- python - 使用 panda 替换给定 csv 日期数据集的开始日期
- javascript - 有没有办法通过 chrome 扩展中的 firebase 提供用户特定的数据?
- python - 如何在替换后删除列表中的元素,在列表中的下一个最大的循环中