【问题标题】:Prolog: efficiency序言:效率
【发布时间】:2016-06-02 08:35:09
【问题描述】:

prolog 中有没有办法缩短以下内容:

rule(prop, [1/2,2/2]).
rule(prop, [1/3,2/3,3/3]).
rule(prop, [1/4,2/4,3/4,4/4]).
rule(prop, [1/5,2/5,3/5,4/5,5/5]).
rule(prop, [1/6,2/6,3/6,4/6,5/6,6/6]).
rule(prop, [1/7,2/7,3/7,4/7,5/7,6/7,7/7]).

【问题讨论】:

    标签: prolog processing-efficiency


    【解决方案1】:

    TL;DR:为什么不委派处理递归的责任——也要把它做好?

    此答案由@lurker 跟进this previous answer。我们没有涵盖整个问题,而是专注于展示如何定义像 list_props/3 这样的谓词,以便将所有递归委托给经过验证的真实 Prolog 谓词 length/2numlist/2maplist/3

    :- use_module(library(between), [numlist/2])。 :- use_module(库(lists), [maplist/3])。

    要自定义通用的 maplist/3,我们定义:

    denom_num_expr(B, A, A/B)。

    使用 4.3.2 的示例查询:

    | ?- length(_Ds, N), numlist(N, _Ds), maplist(denom_num_expr(N), _Ds, Qs)。 N = 1, Qs = [1/1] ? ; N = 2, Qs = [1/2,2/2] ? ; N = 3, Qs = [1/3,2/3,3/3] ? ; N = 4, Qs = [1/4,2/4,3/4,4/4] ? ; N = 5, Qs = [1/5,2/5,3/5,4/5,5/5] ? ; N = 6, Qs = [1/6,2/6,3/6,4/6,5/6,6/6] ? ; N = 7, Qs = [1/7,2/7,3/7,4/7,5/7,6/7,7/7] ? ; N = 8, Qs = [1/8,2/8,3/8,4/8,5/8,6/8,7/8,8/8] ? ; N = 9, Qs = [1/9,2/9,3/9,4/9,5/9,6/9,7/9,8/9,9/9] ? ...

    【讨论】:

    • 是的,获得list_prop/3 (+1) 的方式要优雅得多。除了习惯之外没有什么特别的原因,我倾向于将 gprolog 用于小的 Prolog 任务,它没有 numlist/3,但 numlist/3 很容易创建。
    • 我们需要更多共同点!虽然 SWI 和 SICStus 都提供numlist/3,但它们提供不同的模式 IIRC。 (使用 SICStus,我们可以踢出多余的 length/2 目标。)
    • @lurker。我收回我之前关于“SICStus 为numlist 提供更多(可用)模式”的声明;那是一厢情愿。
    • @lurker。从好的方面来说,SICStus 有numlist/2,这是一个明确的习语。我希望有一天它可以在两个参数都未绑定时作为生成器工作,就像上面与 length/2 结合使用一样。
    【解决方案2】:

    对于 6 种不同规则的情况,以下代码不一定“更短”,但它更具可扩展性,这可能是您真正的意思。

    您可以将其分解如下。一、生成一个列表的规则:

    list_props(N, N, [N/N]).
    list_props(X, N, [X/N|T]) :-
        X >= 1,
        X < N,
        X1 is X + 1,
        list_props(X1, N, T).
    

    当你调用它时,它会生成一个从第一个参数到最后一个参数的比例列表,最后一个参数是分母。例如:

    | ?- list_props(1, 4, L).
    
    L = [1/4,2/4,3/4,4/4] ? a
    
    | ?-
    

    请注意,您可以使用 integer(N) 和条件强制 N 为 >= 1 的整数,但我很简短,在上面没有这样做。

    您可以在顶级谓词中使用它:

    rule(prop, L) :-
        between(2, 7, X),
        list_props(1, X, L).
    

    产量:

    | ?- rule(prop, L).
    
    L = [1/2,2/2] ? ;
    
    L = [1/3,2/3,3/3] ? ;
    
    L = [1/4,2/4,3/4,4/4] ? ;
    
    L = [1/5,2/5,3/5,4/5,5/5] ? ;
    
    L = [1/6,2/6,3/6,4/6,5/6,6/6] ? ;
    
    L = [1/7,2/7,3/7,4/7,5/7,6/7,7/7] ? ;
    
    (2 ms) no
    | ?-
    

    【讨论】:

    • 是的,这很好用。并感谢您的解释!
    猜你喜欢
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多