Prolog 序言:艺术品盗窃。解决逻辑难题

Prolog 序言:艺术品盗窃。解决逻辑难题,prolog,logic,artificial-intelligence,puzzle,negation,Prolog,Logic,Artificial Intelligence,Puzzle,Negation,刚刚开始进入Prolog,因为人工智能非常有趣,与许多其他编程语言不同,我偶然发现了一个逻辑难题: 想知道我如何开始编写这样一个拼图 让我很不安的是,我们知道一些坏信息,你会如何严格地从一组人中选择他们呢?让我们假设我们有一组人和一组说谎者。 您可以将问题分解为两个需求: 说谎者是人的“子列表”:我们需要一个附加谓词,例如子列表(人,说谎者): 说谎者有四种: length(Liars,4) 现在,您可以将其与连词组合在一起: length(Liars,4),sublist(Person

刚刚开始进入Prolog,因为人工智能非常有趣,与许多其他编程语言不同,我偶然发现了一个逻辑难题:

想知道我如何开始编写这样一个拼图


让我很不安的是,我们知道一些坏信息,你会如何严格地从一组人中选择他们呢?让我们假设我们有一组人和一组说谎者。 您可以将问题分解为两个需求:

  • 说谎者
    人的“子列表”
    :我们需要一个附加谓词,例如
    子列表(人,说谎者)

  • 说谎者有四种:

    length(Liars,4)
    
  • 现在,您可以将其与连词组合在一起:

    length(Liars,4),sublist(Persons,Liars)
    

    我把
    长度(撒谎者,4)
    放在前面,因为它是确定的,而
    子列表/2
    创建选择点。

    此代码使用SWI Prolog库(聚合)方便计数

    s(a, b, d, e).
    s(b, a, c, e).
    s(c, b, f, e).
    s(d, a, f, c).
    s(e, c, d, f).
    s(f, c, d, a).
    
    count_lies(T, N) :-
        aggregate_all(count, (s(_, X,Y,Z), (T==X;T==Y;T==Z)), N).
    
    solve(P) :-
        member(P, [a,b,c,d,e,f]), count_lies(P, 4).
    
    测试:


    哇,这很有道理。真的非常感谢,看起来如此简单但逻辑性强的编程对我来说是非常陌生的,很难理解。非常感谢你的帮助!对不起,这很麻烦,但是有人能解释一下“聚合所有”方法吗?我在网上看过,但我真的搞不懂,我确实看到这里x,y,z需要是同一个人(看到x,y,z在列表的最后三部分,这是列表中第一个人的陈述),但是“count”和“N”在这个函数中做什么?
    s(a, b, d, e).
    s(b, a, c, e).
    s(c, b, f, e).
    s(d, a, f, c).
    s(e, c, d, f).
    s(f, c, d, a).
    
    count_lies(T, N) :-
        aggregate_all(count, (s(_, X,Y,Z), (T==X;T==Y;T==Z)), N).
    
    solve(P) :-
        member(P, [a,b,c,d,e,f]), count_lies(P, 4).
    
    ?- solve(P).
    P = c ;
    false.