我想做的是:
fromHistory / 2
fromHistory(HL,FL)
如果列表包含单词" ate"
,则FL是列表的第3个元素如果列表包含所有单词,则FL是列表的第4个元素["你","可以","有"]
谓词应该循环到列表HL列表中,如果其中一个列表包含上面的单词,它应该根据找到的单词附加第3 /第4个元素,否则它不应该是#t; t得到任何东西。
?- fromHistory([[i,ate,x], [you,can,have,y]], FL).
FL = [x, y] ;
false.
?- fromHistory([[this,is,a,useless,input], [i,ate,x], [another,input],
[another,useless,input], ["Ok"], [you,can,have,y]], FL).
FL = [x, y] ;
false.
x和y并不总是在列表的末尾,而是在[" ate"]和["你"," can"之后的字符串, "具有"]
我尝试使用here
中的查找版本find(X,Y,[X,Y|Tail]):-
!.
find(X,Y,[_|Tail]):-
find(X,Y,Tail).
foodFromHistory(HL1, FL):-
flatten(HL1, HL),
find(ate, FL1, HL),
find([you, can, have], FL2, HL),
FL = [FL1|FL2].
然而,它不能与[你,可以,有]并且返回false,它也不会在整个列表上工作,而是仅在第一次出现时。
答案 0 :(得分:1)
根据经验,如果你需要逐个元素地处理一些事物的列表,首先要清楚地知道如何为每个元素做些什么(在这种情况下,这些"元素&#34 ;是输入短语)并实现和测试,而不用担心整个问题。所以:
如果列表包含单词" ate"
,则FL是列表的第3个元素如果列表包含所有单词,则FL是列表的第4个元素["你","可以","有"]
这不是一个非常好的规范,但是这里有一个实现,你可以独立于更大的问题进行测试和调整:
input_food([_Somebody, ate, Food], Food).
input_food(Input, Food) :-
append(_Something, [you, can, have, Food | _Rest], Input).
就是这样!您有两个要求,每个要求描述列表上的简单模式匹配。因此,Prolog实现可以是两个子句,每个子句在列表上实现简单的模式匹配。
让我们测试一下:
?- input_food([i, ate, x], Food).
Food = x ;
false.
?- input_food([you, ate, x], Food).
Food = x ;
false.
?- input_food([ok, you, can, have, strawberries], Food).
Food = strawberries ;
false.
?- input_food([this, sentence, no, food], Food).
false.
好的,我们现在需要做的就是迭代输入列表并收集input_food/2
给出的每个输入的食物(如果有的话)。这是标准的:
inputs_foods([], []).
inputs_foods([I|Is], [Food|Fs]) :-
input_food(I, Food),
inputs_foods(Is, Fs).
inputs_foods([I|Is], Fs) :-
\+ input_food(I, _Food),
inputs_foods(Is, Fs).
似乎主要做你想做的事情:
?- inputs_foods([[this,is,a,useless,input], [i,ate,x], [another,input],
[another,useless,input], ["Ok"], [you,can,have,y]], FL).
FL = [x, y] ;
false.
答案 1 :(得分:0)
我不完全理解prediacte应该如何工作,像[some,input,i,ate,x,some,other,input]
这样的数组呢,它应该将x附加到列表中吗?
您可以尝试创建自己的列表,例如H1 = [i,ate,X|_],
和H2 = [you,can,have,Y|_]
,然后递归遍历HL的成员并比较它们并使您的解决方案用X或Y统一它们。
编辑
我为[i,ate,x]制作了一些东西,现在你必须对[你,可以,有,y]采取类似的方法。
方法是检查列表[i,ate,X]是否是HL的当前成员的子列表,如果是,我们可以将X添加到我们的FL集合中。检查这是否是您所期望的:)
fromHistory(HL,FL) :-
findAnswers(HL,[],FL).
findAnswers([],Answers,Answers).
findAnswers([H|HL],FL,Answers) :-
(isSublist([i,ate,X],H) -> append(FL,[X],FL2); FL2 = FL),
findAnswers(HL,FL2,Answers).
isSublist(SL, L) :-
append([_,SL,_],L).
答案 2 :(得分:0)
您的问题的解决方案可能是:
solve(L,FL,FLO):-
member("ate",L),
\+consequent(L),
nth1(3,L,E),
append(FL,[E],FLO).
solve(L,FL,FLO):-
\+member("ate",L),
consequent(L),
nth1(4,L,E),
append(FL,[E],FLO).
consequent(L):-
nth1(P,L,"you"),
P1 is P+1,
nth1(P1,L,"can"),
P2 is P+2,
nth1(P2,L,"have").
fromHistory([],L,L).
fromHistory([H|T],L,FL):-
solve(H,L,FLO),
fromHistory(T,FLO,FL).
首先,检查ate
是否在列表中,you can have
不在其中。然后,您可以使用nth/3
找到所需的元素,并使用append/3
将其附加到列表中。类似的情况是,您在列表中找到you can have
而ate
不在其中。当您在列表中同时包含ate
和you can have
时,您必须决定要执行的操作。在此实现中,谓词失败。
查询:
?- fromHistory([["you","can","have","hallo","at"],["ate","str1","str2"]],["test","aa"],L).
L = ["test", "aa", "hallo", "str2"]