【问题标题】:Add fact to list if it's not already in如果事实尚未在列表中,则将其添加到列表中
【发布时间】:2013-04-21 15:15:07
【问题描述】:

我需要根据我掌握的事实构建一个列表。例如,我有一个这样的课程列表:

    attend(student1,c1).
    attend(student1,c2).
    attend(student2,c1).
    attend(student2,c3).

现在我想要一个谓词 courselist/2 ,它返回给定学生的课程列表。当然,每门课程都应该只在这个列表中出现一次。我不能使用像 findall 这样的内置谓词,但我可以使用成员或附加。到目前为止,我有这样的事情:

    courselist(S,R) :- attend(S,C), member(C,R), courselist(S,R).
    courselist(S,R) :- attend(S,C), append([C],L,R), courselist(S,R).

我知道这是错误的,但我不知道如何在不陷入无限循环的情况下找到所有事实。

【问题讨论】:

    标签: list prolog


    【解决方案1】:

    不能使用findall/3 是一个愚蠢的限制,因为它是解决此类问题的自然方法。您可以像这样手动操作:

    student_courses(Student, Courses) :-
            student_courses(Student, [], Courses).
    
    student_courses(S, Cs0, Cs) :-
            (   attend(S, C), \+ member(C, Cs0) ->
                student_courses(S, [C|Cs0], Cs)
            ;   Cs = Cs0
            ).
    

    查询示例:

    ?- student_courses(student2, Cs).
    Cs = [c3, c1].
    

    请注意,这不是真正的关系,因为此特定解决方案不会出现在以下更一般的查询中:

    ?- student_courses(Student, Cs).
    Student = student1,
    Cs = [c2, c1].
    

    我把它作为练习留给你,让你以最一般的查询产生所有正确结果的方式实现它。还要注意更具可读性和相关性的谓词名称。

    【讨论】:

      猜你喜欢
      • 2014-04-19
      • 2021-11-04
      • 2019-08-20
      • 2012-02-10
      • 2012-05-11
      • 1970-01-01
      • 2022-10-25
      • 2011-10-30
      • 2010-11-01
      相关资源
      最近更新 更多