相同的结果在Prolog中打印两次

时间:2013-12-01 23:21:56

标签: prolog

我必须创建一个谓词,一餐(A,E,D),根据一些规则找到所有可能的膳食组合。当我测试我的代码时,我得到正确的解决方案,他们只打印两次。这是我的代码:

    %Kris Carneal
    %CMSC 403
    %Project 3

    standardMeal(A,E,D) :- appetizer(A),
    entree(E),
    dessert(D),
    not(A == E),
    not(E == D),
    not(D == A).

    appetizer('Egyptian').
    appetizer('Korean').
    appetizer('Vietnamese').
    appetizer('Mexican').

    entree('Chinese').
    entree('Egyptian').
    entree('Indian').
    entree('Korean').
    entree('Mexican').
    entree('Vietnamese').

    dessert('American').
    dessert('Chinese'). 
    dessert('Egyptian').
    dessert('Indian').
    dessert('Korean').
    dessert('Vietnamese').

    c1(A,E,D) :-
      once(
        A == 'Egyptian';
        E == 'Chinese';
        E == 'Egyptian';
        D == 'Chinese';
        D == 'Egyptian'
      ).

    c2(A,E,D) :- 
      (
        (A == 'Indian', D == 'Korean')
      ;
        not(A == 'Indian')
      ).

    c3(A,E,D) :-
      (
        (D == 'American', not(A == 'Mexican'), not(E == 'Mexican'))
      ;
        (not(D == 'American'))
      ).

    c4(A,E,D) :-
      (
        (A == 'Vietnamese', E == 'Chinese')
      ;
        (D == 'Vietnamese', E == 'Chinese')
      ;
        (not(A == 'Vietnamese'), not(D == 'Vietnamese'), not(E == 'Vietnamese'))
      ).

    c5(A,E,D) :-
      (
        (not(D == 'Korean'), not(A == 'Korean'), not(E == 'Korean'))
      ;
        (E == 'Egyptian', D == 'Korean')
      ;
        (A == 'Egyptian', (E == 'Korean' ; D == 'Korean'))
      ).

    c6(A,E,D) :-
      (
        (A == 'Egyptian' ; E == 'Egyptian'; D == 'Egyptian'),
        (not(D == 'Vietnamese'), not(A == 'Vietnamese'), not(E == 'Vietnamese'))
      ;
        (not(D == 'Egyptian'), not(A == 'Egyptian'), not(E == 'Egyptian'))
      ).

    c7(A,E,D) :-
      (
        (E == 'Indian', A == 'Korean')
      ;
        (D == 'Indian', A == 'Korean')
      ;
        (not(A == 'Indian'), not(D == 'Indian'), not(E == 'Indian'))
      ).

    c8(A,E,D) :-
      (
        (A == 'Chinese', E == 'Korean')
      ;
        (D == 'Chinese', E == 'Korean')
      ;
        (not(A == 'Chinese') ; not(D == 'Chinese'), not(E == 'Chinese'))
      ).

    c9(A,E,D) :-
      (
        (E == 'Mexican', A == 'Egyptian', D == 'Korean')
      ;
        (not(E == 'Mexican'), A == 'Egyptian')
      ;
        (E == 'Mexican', not(A == 'Egyptian'))
      ;
        (not(E == 'Mexican'), not(A == 'Egyptian'))
      ).

    c10(A,E,D) :-
      (
        (E == 'Chinese', D == 'American', A == 'Indian')
      ;
        (not(E == 'Chinese'), D == 'American')
      ;
        (E == 'Chinese', not(D == 'American'))
      ;
        (not(E == 'Chinese'), not(D == 'American'))
      ).

    c11(A,E,D) :-
      (
        (A == 'Mexican', D == 'Korean')
      ;
        not(A == 'Mexican')
      ).

    c12(A,E,D) :-
      (
        (E == 'Chinese', (D == 'American'; A == 'American'))
      ;
        (not(E=='Chinese'), (not(D == 'American'), not(A == 'American')))
      ).


    meal(A,E,D) :-
      standardMeal(A,E,D),
      c1(A,E,D),
      c2(A,E,D),
      c3(A,E,D),
      c4(A,E,D),
      c5(A,E,D),
      c6(A,E,D),
      c7(A,E,D),
      c8(A,E,D),
      c9(A,E,D),
      c10(A,E,D),
      c11(A,E,D),
      c12(A,E,D),
      print(A), print(', '),
      print(E), print(', '),
      print(D), print('\n'),
      fail.

关于如何让我的结果只打印一次的任何线索?

1 个答案:

答案 0 :(得分:0)

我认为问题是c8 / 3成功了两次。验证

?- c8('Egyptian', 'Korean', 'Chinese').
true ;
true ;
false.

当然,使用调试器检查重做/退出序列,从

开始
?- leash(-all),trace,meal('Egyptian', 'Korean', 'Chinese').

然后你需要让你的规则不那么宽松,或者用一次/ 1

来应用它