如何“返回"序言中的值? [英] How to 'return' a value in prolog?

查看:58
本文介绍了如何“返回"序言中的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做的是将两个列表中的元素追加到另一个列表中,最后在控制台中获取新列表的值. 我的列表是:A = [a,b]; B(对列表)= [(c,cc),(a,aa),(b,bb)] 如果第一个元素与对的第一个元素匹配(字典原理),我想添加列表B对的第二个元素(我希望将所有这些元素添加到控制台将输出的空列表中). 到目前为止,我的情况是这样(X是空列表):

What I am trying to do is append elements from two lists into another and in the end get the value of the new list out in console. My lists are : A = [a, b]; B(list of pairs) = [(c, cc), (a, aa), (b, bb)] I want to add the second element of pair of list B if the first element matches the first element of pair (dictionary principle) And I want all those elements to be added in an empty list which the console would output. What I have so far is this (X would be the empty list):

aa(_, [], _) :-
    true.

aa([H|T], [(A, B)|T2], X) :-
    H == A ->
        append([B], X, X2), aa([H|T], T2, X2);
        aa([H|T], T2, X).

在控制台中,我输入:read(X), trace,aa([a, b], [(c, cc), (a, aa), (b, bb)], X), write(X).

In console I'm typing: read(X), trace,aa([a, b], [(c, cc), (a, aa), (b, bb)], X), write(X).

但是它一直返回X的[]值.如果我要X,如何获得X2的值作为输出? 这是跟踪输出:

But it keeps returning the [] value of X. How can I get the value of X2 as output if I am asking for X? Here is the trace output:

 Call:aa([a, b], [(c,cc), (a,aa), (b,bb)], [])
 Call:a==c
 Fail:a==c
 Redo:aa([a, b], [(c,cc), (a,aa), (b,bb)], [])
 Call:aa([a, b], [(a,aa), (b,bb)], [])
 Call:a==a
 Exit:a==a
 Call:lists:append([aa], [], _2110)
 Exit:lists:append([aa], [], [aa])
 Call:aa([a, b], [(b,bb)], [aa])
 Call:a==b
 Fail:a==b
 Redo:aa([a, b], [(b,bb)], [aa])
 Call:aa([a, b], [], [aa])
 Exit:aa([a, b], [], [aa])
 Exit:aa([a, b], [(b,bb)], [aa])
 Exit:aa([a, b], [(a,aa), (b,bb)], [])
 Exit:aa([a, b], [(c,cc), (a,aa), (b,bb)], [])
 Call:write([])
[]
 Exit:write([])

推荐答案

;放在行尾不是一个好主意,很容易忽略它.我希望使用其他格式,请参见下文.对于您的问题,您以错误的顺序输入了append/3的参数. X2是递归调用的中间结果,而您要返回"的结果是此X2与元素B的组合:

It's not a good idea to put the ; at the end of a line, it is very easy to overlook it. I prefer a different format, see below. As for your question, you have the arguments to append/3 in the wrong order. X2 is the intermediate result from the recursive call, and the result you want to "return" is the combination of this X2 with the element B:

aa(_, [], _) :-
    true.

aa([H|T], [(A, B)|T2], X) :-
    (   H == A
    ->  append([B], X2, X), aa([H|T], T2, X2)
    ;   aa([H|T], T2, X) ).

目标append([B], X2, X)可以更清晰地写为X = [B|X2].

The goal append([B], X2, X) can be written more clearly as X = [B|X2].

这解决了眼前的问题,但尚未解决整个谓词:

This fixes the immediate problem, but not yet the whole predicate:

?- aa([a, b], [(c, cc), (a, aa), (b, bb)], X).
X = [aa|_G22] ;
false.

您将第一个参数分解为[H|T],但实际上并未对此列表进行递归,因此您永远不会查看b及其对列表中的对应元素.

You decompose the first argument into [H|T] but don't actually do a recursion over this list, so you never look at b and its corresponding element in the list of pairs.

这是完成整件事的一种简单方法:

Here's a simple way to do the whole thing:

aa([], _Pairs, []).
aa([Key|Keys], Pairs, Values) :-
    (   member((Key, Value), Pairs)
    ->  aa(Keys, Pairs, Values0),
        Values = [Value|Values0]
    ;   aa(Keys, Pairs, Values) ).

此处的主要见解是,一旦您知道Key,就可以在对列表中寻找对(Key, Value). Value尚未绑定到值,并且如果列表包含一对第一个元素为Key的对,则会由member/2实例化.这就是统一的力量!

The key insight here is that once you know a Key, you can look for a pair (Key, Value) in your list of pairs. Value is not bound to a value yet and will be instantiated by member/2 if it the list contains a pair whose first element is Key. This is the power of unification!

这似乎可行:

?- aa([a, b], [(c, cc), (a, aa), (b, bb)], X).
X = [aa, bb].

最后,您可能不想在此之前输入read(X),因为这意味着用户必须预测解决方案!

Finally, you probably don't want to have a read(X) before this, since that means that the user must predict the solution!

这篇关于如何“返回"序言中的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆