【问题标题】:Printing out a dynamically sized truth table using lists in prolog使用序言中的列表打印出动态大小的真值表
【发布时间】:2021-01-31 20:09:33
【问题描述】:

我创建了一个子句table,用于创建一个给定 2 个前提和 3 个谓词以及一个结论的真值表:

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 子句映射到列表的方法,这样我们就可以打印出该列表。为代码墙道歉。谢谢

【问题讨论】:

    标签: prolog


    【解决方案1】:

    因此,我想知道是否有办法知道您是否在此函数中回溯(以便我们可以重新打印该行上较早的值)。

    可能有一些巧妙的技巧可以做到这一点,但对于对问题的令人困惑的解释来说,这将是一个非常令人困惑的解决方案。问题本身很简单:

    或者也许是一种将 bool 子句映射到列表的方法,以便我们可以打印出该列表。

    是的。而且您已经知道该怎么做,因为这就是您在writePredicates 内部所做的事情!您唯一缺少的是,您应该在开始打印之前对完整的布尔列表进行“标记”,而不是交错标记和打印单个元素。

    所以你只需要这个:

    bools([]).
    bools([Bool | Bools]) :-
        bool(Bool),
        bools(Bools).
    
    tableMoreDynamic(Predicates,Premises, Conclusion):-
        bools(Predicates),
        writePredicates(Predicates),
        ...
    

    保持其余代码不变。 (您可以删除writePredicates 中的bool 调用,它不再执行任何操作。)

    这会打印完整的表格:

    ?- 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 谓词。

    【讨论】:

    • 效果很好!我一直在寻找 maplist 的替代方案,但使用 GNUProlog 却找不到等价物,但您的解决方案实际上非常简单!感谢您的帮助
    猜你喜欢
    • 2016-02-15
    • 2018-01-24
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 2021-05-25
    • 1970-01-01
    相关资源
    最近更新 更多