在Prolog编程中,计算Y实际发生的次数(X,Y)

在Prolog编程中,计算Y实际发生的次数(X,Y),prolog,Prolog,我是prolog编程新手,我正在尝试使用它 我有两个问题 假设我有一些事实 事实('A','B')。 事实('A','C')。 事实('A','D') 当我写事实('A',X'时,X将是3个值'B','C','D' 我如何编写一个规则来获得“a”有一对的次数,在这种情况下,答案是3 假设我有一个事实 a([1,2,4,5]) 我如何编写一个规则来循环元素以添加它们,即找到sigma 谢谢您可以收集解决方案列表并获取列表大小: ?- findall(X, fact('A',X), List),

我是prolog编程新手,我正在尝试使用它 我有两个问题

  • 假设我有一些事实

    事实('A','B')。 事实('A','C')。 事实('A','D')

  • 当我写事实('A',X'时,X将是3个值'B','C','D' 我如何编写一个规则来获得“a”有一对的次数,在这种情况下,答案是3

  • 假设我有一个事实

    a([1,2,4,5])

  • 我如何编写一个规则来循环元素以添加它们,即找到sigma


    谢谢

    您可以收集解决方案列表并获取列表大小:

    ?- findall(X, fact('A',X), List), length(List,Count).
    List = ['B', 'C', 'D'],
    Count = 3.
    
    或者更好地使用以下聚合谓词:


    注意插入符号
    X^
    表示
    X
    不是一个变量,在该变量上
    聚合(count,Goal_,with_X,count)。
    应该回溯(给出三次1的计数)但是
    目标的一个自由变量带有_X
    ,该变量随溶液袋的大小而变化,应评估溶液袋的大小。

    您可以收集溶液列表并获得列表的大小:

    ?- findall(X, fact('A',X), List), length(List,Count).
    List = ['B', 'C', 'D'],
    Count = 3.
    
    或者更好地使用以下聚合谓词:


    注意插入符号
    X^
    表示
    X
    不是一个变量,在该变量上
    聚合(count,Goal_,with_X,count)。
    应该回溯(给出三次1的计数)但是,
    目标的一个自由变量带有_X
    ,该变量随溶液袋的大小而变化,应评估溶液袋的大小。

    如果您只需要计算溶液,并且您正在使用SWI Prolog,请使用
    聚合\u all

    ?- aggregate_all(count, fact('A', _), N).
    
    这样,您就不需要对变量进行存在性限定,只需在查询中使用匿名变量来“跳过”它即可

    这还可以正确计算0个解决方案,而无需进一步的代码技巧:

    ?- aggregate_all(count, fail, N).
    
    要对列表求和,可以使用库(列表)中的
    sum\u list/2
    。请注意,如果您有一个可回溯谓词(事实表)而不是列表,那么也可以使用库(聚合)来实现这一点。这也是表示数据库中事物的“列表”的更常见的方法

    a(1).
    a(2).
    a(4).
    a(5).
    
    这是您通常如何查找表中所有行的总和:

    ?- aggregate_all(sum(X), a(X), Sum).
    Sum = 12.
    
    当然,表中可以有更多的列

    p(a, 3).
    p(b, 2).
    p(b, 1).
    p(a, 2).
    p(a, 0).
    
    你可以这样求和:

    ?- aggregate_all(sum(X), p(a, X), Sum).
    Sum = 5.
    
    ?- aggregate_all(sum(X), p(b, X), Sum).
    Sum = 3.
    
    ?- aggregate_all(sum(X), p(foo, X), Sum).
    Sum = 0.
    
    ?- aggregate_all(sum(X), p(_, X), Sum). % total sum
    Sum = 8.
    
    相反,您可以使用
    aggreagate
    获取不同的组:

    ?- aggregate(sum(X), p(A, X), Sum).
    A = a,
    Sum = 5 ;
    A = b,
    Sum = 3.
    

    如果您只需要计算解决方案并使用SWI Prolog,请使用
    aggregate\u all

    ?- aggregate_all(count, fact('A', _), N).
    
    这样,您就不需要对变量进行存在性限定,只需在查询中使用匿名变量来“跳过”它即可

    这还可以正确计算0个解决方案,而无需进一步的代码技巧:

    ?- aggregate_all(count, fail, N).
    
    要对列表求和,可以使用库(列表)中的
    sum\u list/2
    。请注意,如果您有一个可回溯谓词(事实表)而不是列表,那么也可以使用库(聚合)来实现这一点。这也是表示数据库中事物的“列表”的更常见的方法

    a(1).
    a(2).
    a(4).
    a(5).
    
    这是您通常如何查找表中所有行的总和:

    ?- aggregate_all(sum(X), a(X), Sum).
    Sum = 12.
    
    当然,表中可以有更多的列

    p(a, 3).
    p(b, 2).
    p(b, 1).
    p(a, 2).
    p(a, 0).
    
    你可以这样求和:

    ?- aggregate_all(sum(X), p(a, X), Sum).
    Sum = 5.
    
    ?- aggregate_all(sum(X), p(b, X), Sum).
    Sum = 3.
    
    ?- aggregate_all(sum(X), p(foo, X), Sum).
    Sum = 0.
    
    ?- aggregate_all(sum(X), p(_, X), Sum). % total sum
    Sum = 8.
    
    相反,您可以使用
    aggreagate
    获取不同的组:

    ?- aggregate(sum(X), p(A, X), Sum).
    A = a,
    Sum = 5 ;
    A = b,
    Sum = 3.
    

    @NickyPratama要在列表上求和,实际上有一个谓词,所以你可以这样做:
    a(L),sum\u list(L,sum)。
    @NickyPratama注意,
    aggregate/3有一个边缘情况:如果没有解决方案,则如果失败,而不是给出
    Count==0
    。使用
    (聚合(count,X^事实(c,X),count)->true;count=0)。
    确保您得到的
    计数
    为0,而不是失败。您可以使用
    聚合\u all
    来代替,它更明显,并且不会在您的注释中出现边缘情况。Try:
    ?-aggregate\u all(count,介于(1,3,u),N)之间)。
    (不需要“存在限定变量”)和
    ?-aggregate\u all(count,fail,N)。
    与bagof/setof和findall在语义和实现上的差异有点相关。另请参阅文档。@NickyPratama您在事实中有您的数字列表:
    a([1,2,4,5])。
    。因此,首先,您必须从事实中获取该列表并将其放入变量中,这样做:
    a(L)。
    。现在
    L
    [1,2,4,5]
    。现在您可以执行'sum_list(L,sum)。
    。但是当然,在执行单个目标的上下文中,
    L`只是相同的
    L
    (否则它就完全不同了
    L
    s),所以您将两条指令一起运行到一个目标中:
    a(L),sum\u list(L,sum)。
    @NickyPratama完整的故事是,您几乎永远不会保存这样的事实:
    a([1,2,4,5])
    ,这通常被写成一个表。看到我的答案了。@NickyPratama要在列表上求和,实际上有一个谓词,所以你可以这样做:
    a(L),sum\u list(L,sum)。
    @NickyPratama注意,
    aggregate/3
    有一个边缘情况:如果没有解决方案,则不给出
    Count==0
    。使用
    (聚合(count,X^事实(c,X),count)->true;count=0)。
    确保您得到的
    计数
    为0,而不是失败。您可以使用
    聚合\u all
    来代替,它更明显,并且不会在您的注释中出现边缘情况。Try:
    ?-aggregate\u all(count,介于(1,3,u),N)之间)。
    (不需要“存在限定变量”)和
    ?-aggregate\u all(count,fail,N)。
    与bagof/setof和findall在语义和实现上的差异有点相关。另请参阅文档。@NickyPratama您在事实中有您的数字列表:
    a([1,2,4,5])。
    。因此,首先,您必须从事实中获取该列表并将其放入变量中,这样做:
    a(L)。
    。现在
    L
    [1,2,4,5]
    。现在您可以执行'sum_list(L,sum)。
    。但是当然,在一个要执行的单一目标的上下文中,
    L`只是相同的
    L