【问题标题】:Arithmetic in Prolog - Multiples of a numberProlog中的算术 - 数字的倍数
【发布时间】:2021-05-09 04:49:39
【问题描述】:

我想创建一个函数multiples(X, N, R),其中R 是一个列表,其中包含从XX * NX 的所有倍数。

一个例子是:multiples(3, 4, [12, 9, 6, 3]),它应该给出 true。

到目前为止我的代码:

multiples(X, N, R) :- X >= 1, N >= 1, Z is X*N, contains(Z, R).

contains(Z, [Z|_]).
contains(Z, [W|V]) :- contains(Z,V), L is Z-X, L >= X, contains(L, V).

multiples(3,4,X). 的控制台输出为X = [12|_xxxx],当我输入; 时出现错误。
我如何设法接收我想要的列表?
(也许我的想法完全错误)。

【问题讨论】:

    标签: list prolog arithmetic-expressions


    【解决方案1】:

    对您的代码稍作修改。 contains predicate 将收集一个列表中的数字,N 将不断减少,直到满足基本谓词。

    multiples(X, N, R) :- X >= 1, N >= 1, contains(X,N, R),!.
    
    contains(_,0,[]).
    contains(X,N,[Z|List]):-
        Z is X*N,
        N1 is N-1,
        contains(X,N1,List).
    

    示例:

    ?- multiples(3,4,R).
    R = [12, 9, 6, 3]
    
    ?- multiples(2,5,R).
    R = [10, 8, 6, 4, 2]
    
    ?- multiples(25,5,R).
    R = [125, 100, 75, 50, 25]
    

    【讨论】:

    • 谢谢!有没有办法删除“!”没有第二个答案会导致无限循环,只是好奇。
    • 是的,将它从​​复数谓词中删除并添加到 contains ( contains(_,0,[]):-!.)
    【解决方案2】:

    我发现您的代码存在 4 个问题。这是固定代码,解释如下:

    multiples(X, N, R) :- 
        X >= 1, 
        N >= 1, 
        Z is X*N, 
        contains(X, Z, R).
    
    contains(X, Z, [Z|V]) :- 
        L is Z-X, 
        L >= X, 
        contains(X, L, V).
    contains(_, Z, [Z]).
    
    ?- multiples(3,4,X).
    X = [12, 9, 6, 3] ;
    X = [12, 9, 6] ;
    X = [12, 9] ;
    X = [12] ;
    false.
    

    首先在您的 contains 谓词中访问 XW 并且从不说明它们的值。通过向谓词添加另一个属性来解决X。通过将W 替换为Z 来解决它。

    另一个问题是规则的顺序。较大的 contains 规则应该是“主要”规则,只有当这个规则失败时,另一个应该“触发”。通过将默认规则放在顶部,您会得到正确的结果。

    同样规则contains(_, Z, [Z]). 标记结束,因此返回列表中只有元素Z,并且不包含任何其他(未知)元素。

    最后一点是您不需要在主 contains 规则中调用两个 contains

    该示例适用于第一个答案。但是,您可以通过削减 (!) 来改进这一点,这样可以防止在成功访问第一条规则后转到第二条规则:

    contains(X, Z, [Z|V]) :- 
        L is Z-X, 
        L >= X, 
        !,
        contains(X, L, V).
    contains(_, Z, [Z]).
    
    ?- multiples(3,4,X).
    X = [12, 9, 6, 3].
    

    【讨论】:

    • 感谢您提供非常好的答案!现在我明白我做错了什么:)
    猜你喜欢
    • 2019-07-09
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2011-04-10
    • 1970-01-01
    相关资源
    最近更新 更多