【问题标题】:setof/3 inside setof/3 not working, but why?setof/3 里面的 setof/3 不工作,但为什么呢?
【发布时间】:2020-03-08 19:07:23
【问题描述】:

灵感来自

Find mutual element in different facts in swi-prolog

我想尝试一下“Prolog 中的 RDBMS 操作”(实际上,这或多或少是 Datalog)

问题陈述

给定一个“主演电影演员”的数据库:

starsin(a,bob).
starsin(c,bob).

starsin(a,maria).
starsin(b,maria).
starsin(c,maria).

starsin(a,george).
starsin(b,george).
starsin(c,george).
starsin(d,george).

给定一组电影,找出在该组所有电影中出演的演员。

我最初有一个丑陋的解决方案,但后来......

很好的解决方案

澄清问题:

集合由不重复的列表表示,可能是有序的。

  1. 给定一组电影 MovIn
  2. ... 找到 Actor 集 ActOut
  3. ... ... 这样:ActOut 中的每个演员 都出现在(至少)MovIn 中的所有电影中
  4. ... ... 重新制定:电影集 MovAx 的任何演员 AxActOutMovIn 的超集。

setof/3 似乎是正确的顶级谓词。第 1 点和第 2 点的 Ansatz 是:

setof(Ax, (... MovIn ...) , ActOut).

如果MovAxAx 出现的电影集,我们可以使用

让我们使用subset/2

第 4 点似乎让我们写作:

setof(Ax, (..., subset(MovAx, MovIn)) , ActOut).

开发... ...

setof(Ax, ( setof(Mx,starsin(Mx,Ax),MovAx) , subset(MovIn, MovAx) ) , ActOut).

这似乎已经是它了!

当有 λ 表达式但有 键盘上或语法中没有 λ。

完成!

总结为谓词:

actors_appearing_in_movies(MovIn,ActOut) :-
   setof(Ax, ( setof(Mx,starsin(Mx,Ax),MovAx) , subset(MovIn, MovAx) ) , ActOut).

不幸的是,上述方法不起作用。

正在进行回溯,显然我需要将所有内容包装到另一个 setof/3 中, 但为什么??

?- actors_appearing_in_movies([a,b],ActOut).
ActOut = [maria] ;
ActOut = [george].

完成,拿两个

以下有效

subselect(Ax,MovIn) :- 
   setof(Mx,starsin(Mx,Ax),MovAx), subset(MovIn, MovAx).
actors_appearing_in_movies(MovIn,ActOut) :- 
   setof(Ax, subselect(Ax,MovIn) , ActOut).
?- actors_appearing_in_movies([a,b],ActOut).
ActOut = [george, maria].

测试

测试只是运行几个目标。

请注意,对于空电影集,我们获取所有演员。这可以说是正确的: 每个演员都出演了空场的所有电影。

actors_appearing_in_movies([],ActOut),permutation([bob, george, maria],ActOut),!. 
actors_appearing_in_movies([a],ActOut),permutation([bob, george, maria],ActOut),!.
actors_appearing_in_movies([a,b],ActOut),permutation([george, maria],ActOut),!.
actors_appearing_in_movies([a,b,c],ActOut),permutation([george, maria],ActOut),!.
actors_appearing_in_movies([a,b,c,d],ActOut),permutation([george],ActOut),!.

问题

我错过了什么

actors_appearing_in_movies(MovIn,ActOut) :-
   setof(Ax, ( setof(Mx,starsin(Mx,Ax),MovAx) , subset(MovIn, MovAx) ) , ActOut).

【问题讨论】:

    标签: prolog prolog-setof


    【解决方案1】:

    试试:

    actors_appearing_in_movies(MovIn,ActOut) :-
        setof(
            Ax,
            MovAx^(setof(Mx,starsin(Mx,Ax),MovAx), subset(MovIn,MovAx)),
            ActOut
        ).
    

    如果没有对 MovAx 变量进行存在限定,您将获得每个变量绑定的解决方案。

    示例调用:

    ?- actors_appearing_in_movies([a,b],ActOut).
    ActOut = [george, maria].
    

    【讨论】:

    • 嗯,这很简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多