基于点积的Prolog递归生成列表

基于点积的Prolog递归生成列表,prolog,Prolog,嗨,我有一个prolog函数/谓词?这是两个列表的点积。我想用它来写一个函数,从一个列表和一个列表中构建一个点产品列表。所以基本上,点积将在列表中的每个列表上调用,函数点在下面,它工作 dot([], [], 0). dot([Head|Tail], [Head2|Tail2], Result) :- Prod = Head * Head2, dot(Tail, Tail2, Remaining), Result is Prod + Remaining. 这是我每次尝

嗨,我有一个prolog函数/谓词?这是两个列表的点积。我想用它来写一个函数,从一个列表和一个列表中构建一个点产品列表。所以基本上,点积将在列表中的每个列表上调用,函数点在下面,它工作

dot([], [], 0).
dot([Head|Tail], [Head2|Tail2], Result) :-
    Prod = Head * Head2,
    dot(Tail, Tail2, Remaining),
    Result is Prod + Remaining. 
这是我每次尝试运行该函数时都失败的尝试。有人能帮忙吗

dotAll([], [[]], [0]).
dotAll(X, [[Head]|[Tail]], Result) :-
    dotUnit(X, Head, Prod),
    Result = [Prod|Result],
    dotAll(X, Tail, Result).
作为我目标的总结,如果我通过了这个
dotAll([1,2,3],[1,2,3],[4,5,6],[1,2,3],什么)。
我想回去,
什么是
[15,32,15]


我知道这是一个满嘴的问题,但我希望有人能给我一些我做错了什么的建议。我对序言很陌生

我认为
dotAll
谓词(来自示例)定义为:

dotAll(Vector, ListOfVectors, Results)
并且表示,
Results
是通过将
向量
的点积与
向量列表
中的每个向量进行比较而获得的点积结果列表

查看
dotAll
谓词:

dotAll(X, [Head|Tail], [Prod|Result]) :-  % dotAll of X with [Head|Tail]
                                          %   is [Prod|Result] if...
    dot(X, Head, Prod),                   % Prod is the dot product of X w/Head
    %Result = [Prod|Result],              % This would always fail
    dotAll(X, Tail, Result).              % AND Result is the list of
                                          %   dot products of X with Tail
关于递归案例的注释:

  • Result=[Prod | Result]
    将失败,因为这是说,我有
    Result
    ,这与
    [Prod | Result]
    是一样的,不可能是真的
  • 如图所示,您可以使用子句中的第三个参数来表示递归情况下结果列表的外观(
    [Prod | result]
  • 那么基本情况是:

    dotAll(_, [], []).                       % dot product of anything with
                                             % an empty list of vectors is empty
    
    关于基本情况的说明:

    dotAll(_, [], []).                       % dot product of anything with
                                             % an empty list of vectors is empty
    
  • 第一个参数不是
    []
    ,因为递归谓词不会将第一个参数缩减为空列表。第一个参数始终是您开始使用的向量,用于与向量列表中的元素进行点积(第二个参数)。因为我们不关心基本情况下的向量是什么,所以我们使用
    \uu
  • 第二个参数是
    []
    ,这是一个空列表,因为基本情况是当我们用尽向量列表(一个列表)时会发生什么。当您到达列表列表的末尾时,您有一个空列表(
    []
  • 第三个参数是空列表
    []
    而不是
    [0]
    ,因为它符合逻辑:如果使用空向量列表获取任何向量的点积,则不应得到任何结果(空列表
    []
  • 使用上述更正:

    | ?- dotAll([1,2,3],[[1,2,3],[4,5,6],[7,8,9]], R).
    
    R = [14,32,50] ? ;
    
    no
    

    请注意,
    [Head]
    是一个包含一个元素的列表,
    Head
    [Tail]
    是一个包含一个元素的列表,
    Tail
    。所以
    [[Head]|[Tail]]
    是由两个元素组成的列表,
    [Head]
    [Tail]
    。你可能不是那个意思。查询
    dotAll([1,2,3],[1,2,3],[4,5,6],[1,2,3]],What)。
    然后失败,因为
    [[1,2,3],[4,5,6],[1,2,3]
    不是一个只有两个元素的列表。在Prolog中,只需将其视为一个列表:
    [Head | Tail]
    。您的
    dotUnit
    将正确处理列表。同样,
    [[]]
    也不是空列表。这是一个包含一个元素的列表,
    []
    。好吧,我把列表列表当作列表。尽管如此,如果我去掉额外的括号,我仍然会失败。我真的看不出逻辑有什么问题。