Prolog'如何返回'一个值

时间:2016-05-05 19:56:47

标签: prolog clpfd

我知道prolog没有返回值,但是我需要更新某个变量的值并使用此过程在控制台中获取它:

#include<stdio.h>
#include<stdlib.h>

int inner_product(int *a, int *b, int size)
{
    int sum = 0, i;

    for (i = 0; i < size; ++i)
    {
        printf("enter value for first array: ");
        scanf("%d", &(a + i));
    }

    for (i = 0; i < size; ++i)
    {
        printf("enter value for first array: ");
        scanf("%d", &(b + i));
    }

    for (i = 0; i < size; ++i)
        sum += *(a + i) * *(b + i);

    return sum;
}

int main()
{
    int n, a, b;
    printf("How many elements do you want to store?  ");
    scanf("%d", &n);

    printf("%d", inner_product(&a, &b, n));

    system("pause");
    return 0;
}

它只需要一个元组列表,并给出该tupes的第二个元素的最大值。

这是我的输出

max(A,B,C) :- (A>B -> C is A ; C is B).                                                   
maxAltura([],RES).
maxAltura([c(X,Y)|[]],RES) :- max(RES,Y, SUM).
maxAltura([c(X,Y)|R1],RES) :- RES>Y, maxAltura(R1,RES).
maxAltura([c(X,Y)|R1],RES) :- RES<Y, maxAltura(R1,Y).
maxAltura([c(X,Y)|R1],RES) :- RES=:=Y, maxAltura(R1,Y).

正如你所看到的,它保持10为最大值,因为我需要像MAX = 10这样的东西。为什么只是给我真实的?

2 个答案:

答案 0 :(得分:2)

您可以使用库(clpfd)更改给定的解决方案以在两个方向上工作。只要列表被充分实例化为/ 2且&gt; / 2工作正常,但只要您尝试将它们与未绑定的变量一起使用,您就会遇到麻烦。请考虑以下示例:

   ?- maxAltura(L,M).
L = [c(_A,M)] ? ;
     ERROR at  clause 1 of user:max/3 !!
     INSTANTIATION ERROR- =:=/2: expected bound value

幸运的是,这可以使用clpfd来解决。在我的原始答案中,我建议简单地用#= / 2和#&gt;替换max / 3中的/ 2和&gt; / 2。像这样:

:- use_module(library(clpfd)).

max(A,B,C) :- A#>B -> C #= A ; C #= B.

% use @CapelliC's maxAltura/2 here

然而,正如@mat和@false在评论中指出的那样,这会产生过于具体/不完整的答案。因此,我建议您按照注释中的建议定义max / 3,例如:

:- use_module(library(clpfd)).

max(A,B,C) :- max(A,B) #= C.

% use @CapelliC's maxAltura/2 here

您使用的示例查询仍然按预期工作:

   ?- maxAltura([c(1,8),c(5,0),c(6,4),c(10,0),c(11,10),c(12,0)],M).
M = 10 ? ;
no

以上两个参数都是变量的查询现在也可以使用:

   ?- maxAltura(L,M).
L = [c(_A,M)] ? ;
L = [c(_A,_B),c(_C,_D)],
M#>=_B,
M#=max(_D,_B),
M#>=_D ? ;
L = [c(_A,_B),c(_C,_D),c(_E,_F)],
M#>=_B,
M#=max(_G,_B),
M#>=_G,
_G#>=_D,
_G#>=_F,
_G#=max(_F,_D) ? 
...

答案 1 :(得分:1)

这个简化版本将最大值绑定为最后一个参数。

max(A,B,C) :- A>B -> C is A ; C is B.

maxAltura([c(_,Y)],Y).
maxAltura([c(_,Y)|R1],RES) :- maxAltura(R1,T), max(T,Y,RES).

请注意,max / 3无用:您可以写

maxAltura([c(_,Y)|R1],RES) :- maxAltura(R1,T), RES is max(T,Y).

此外,使用库(aggregate),您可以进一步简化:

maxAltura(L,MaxY) :- aggregate(max(Y), X^member(c(X,Y),L), MaxY).