如何缩短根据条件打印的谓词

How to shortern a predicate that prints depending on a condition

所以我有这样的东西:

main :-
% Check whether B,C,D is equal to A
... ,

% Relevant code:

    (
         (B==A -> write('B is the same as A.'));
         (C==A -> write('C is the same as A.'));
         (D==A -> write('D is the same as A.'));

    ).

有什么方法可以缩短它但仍然打印相关字母吗?可能有 100 个字母要测试,所以当前的方法不是很好。

如果您没有意识到这种差异,请快速注意一下:当您调用 A == B 时,您正在休息是否绑定到变量 A 的值是 equivalent 到绑定到变量 B 的值。但是当你使用 write/1 输出 'B is the same as A.',你只是在输出那串字母所代表的原子文字。作为原子的一部分的字符 'A' 与源代码中由 A(无 ')表示的变量绑定的值之间没有关系。

所以我不是 100% 清楚您的预期结果,但这里有两个不同的解决方案,展示了使用 format 系列谓词来输出值和文字:

如果你只是想比较两个变量的值,你可以使用一个谓词来执行比较并打印出想要的结果,然后可以在列表的所有成员上使用(forall/2在这里很合适,因为我们只关心输出):

report_on_equality(A, B) :-
    A ==  B, 
    format('~w is the same as ~w.~n', [A, B]).
report_on_equality(A, B) :-
    A \== B, 
    format('~w is not the same as ~w.~n', [A, B]).

example_1 :-
    Vals = [1,4,6,1,7],
    forall( member(V, Vals),
            report_on_equality(V, 1)
          ).

但是在这种情况下没有理由两次输出变量的值,因为如果它们等价,它们当然是相同的值。所以也许你真的想打印出以前与值相关联的大写字符。当然,这要求您首先在大写字符和其他一些值之间进行一些配对。为此,我选择使用 pairs 的简单列表:

report_on_labeled_equality(LabelA-ValA, LabelB-ValB) :-
    ValA == ValB,
    format('~w is the same as ~w.~n', [LabelA, LabelB]).
report_on_labeled_equality(LabelA-ValA, LabelB-ValB) :-
    ValA \== ValB,
    format('~w is not the same as ~w.~n', [LabelA, LabelB]).

example_2 :-
    Vals = ['B'-1, 'C'-3, 'D'-1, 'E'-4],
    forall( member(V, Vals),
            report_on_labeled_equality(V, 'A'-1)
          ).