【问题标题】:Generate lists with independent variables in Prolog在 Prolog 中生成具有自变量的列表
【发布时间】:2021-05-21 21:40:04
【问题描述】:

我在创建将用于填写的列表时遇到问题。我正在尝试使用自变量创建它,以便我可以将地图列表与其他列表统一起来。 为此,我做了:

length(Subs, Len),
maplist(=([_, _, _]), Subs),

但是,这会导致:

Subs = [[_22998, _23020, _23042], [_22998, _23020, _23042], [_22998, _23020, _23042]].

所以,当我尝试统一下一条路时:

maplist(nth1(1), Subs, Com1),
maplist(nth1(2), Subs, Perm_sub),
maplist(nth1(3), Subs, Com3).

与:

Perm_sub = [5, 7, 6],
Com1 = [P23, P34, P36],
Com3 = [1, 3, 2].

它失败了,因为 5 与 _22998 统一,因此与 7 发生冲突。有没有一种简单、优雅的方式来做我想做的事情,或者我是否必须创建一个新函数来处理这个问题,如果是,怎么办我做这个功能?

【问题讨论】:

    标签: prolog


    【解决方案1】:

    您可以创建一个辅助谓词,如下所示:

    triple([_, _, _]).
    

    然后问:

    ?- length(L, 3), maplist(triple, L).
    L = [[_2404, _2410, _2416], [_2422, _2428, _2434], [_2440, _2446, _2452]].
    

    或者,您可以使用 lambda 表达式,如下所示:

    ?- length(L, 3), maplist([[_,_,_]]>>true, L).
    L = [[_7198, _7204, _7210], [_7276, _7282, _7288], [_7354, _7360, _7366]].
    

    编辑 2021 年 10 月 5 日

    请注意,术语中使用的变量与其环境共享(它们是“全局的”,而不是 lambda 绑定的),因此,它们会在所有 maplist 调用中持续存在。例如,在以下查询中,变量 X 被实例化为 1,之后,其值将持续到下一次调用。

    ?- trace, maplist(=(X), [1,Y,1]).
    ^  Call: (11) apply:maplist(=(_1882), [1, _1892, 1]) ? creep
       Call: (12) apply:maplist_([1, _1892, 1], user: =(_1882)) ? creep
       Call: (13) _1882=1 ? creep
       Exit: (13) 1=1 ? creep
       Call: (13) apply:maplist_([_1892, 1], user: =(1)) ? creep
       Call: (14) 1=_1892 ? creep
       Exit: (14) 1=1 ? creep
       Call: (14) apply:maplist_([1], user: =(1)) ? creep
       Call: (15) 1=1 ? creep
       Exit: (15) 1=1 ? creep
       Call: (15) apply:maplist_([], user: =(1)) ? creep
       Exit: (15) apply:maplist_([], user: =(1)) ? creep
       Exit: (14) apply:maplist_([1], user: =(1)) ? creep
       Exit: (13) apply:maplist_([1, 1], user: =(1)) ? creep
       Exit: (12) apply:maplist_([1, 1, 1], user: =(1)) ? creep
    ^  Exit: (11) apply:maplist(user: =(1), [1, 1, 1]) ? creep
    X = Y, Y = 1.
    

    另一方面,用作谓词参数的变量是“本地的”,并且它们的实例化不会从一个调用到另一个调用。例如:

    ?- [user].
    |    equal(_X).
    |    ^Z
    % user://1 compiled 0.02 sec, 1 clauses
    true.
    
    ?- trace, maplist(equal, [1,Y,1]).
    ^  Call: (11) apply:maplist(equal, [1, _1752, 1]) ? creep
       Call: (12) apply:maplist_([1, _1752, 1], user:equal) ? creep
       Call: (13) equal(1) ? creep
       Exit: (13) equal(1) ? creep
       Call: (13) apply:maplist_([_1752, 1], user:equal) ? creep
       Call: (14) equal(_1752) ? creep
       Exit: (14) equal(_1752) ? creep
       Call: (14) apply:maplist_([1], user:equal) ? creep
       Call: (15) equal(1) ? creep
       Exit: (15) equal(1) ? creep
       Call: (15) apply:maplist_([], user:equal) ? creep
       Exit: (15) apply:maplist_([], user:equal) ? creep
       Exit: (14) apply:maplist_([1], user:equal) ? creep
       Exit: (13) apply:maplist_([_1752, 1], user:equal) ? creep
       Exit: (12) apply:maplist_([1, _1752, 1], user:equal) ? creep
    ^  Exit: (11) apply:maplist(user:equal, [1, _1752, 1]) ? creep
    true.
    

    【讨论】:

    • 谢谢,它成功了,但是,你能解释一下为什么我的尝试失败了,为什么它通过 maplist 对 '_' 使用相同的变量?
    • @JavierdeMullerSanta-María 请在我的回答中查看编辑!
    • 谢谢,我明白了,我认为变量''的属性,如果你在不同的规则上使用它,一旦prolog实例化它就会有不同的内部变量,将在这个调用中保留,但我看到的是Prolog将一个变量与这个''的调用相关联,然后重复使用它。
    猜你喜欢
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多