在 Prolog 中将一个子列表等同于 CYK table 的另一个子列表
Equating a Sublist to Another Sublist for CYK table in Prolog
我目前正在开发一个 Prolog 程序,该程序将在获得一组作品后生成 CYK 解析 table。但是,我无法检查两行以查看它们是否相等。这是我目前所拥有的:
answer(X,X).
%Checks to see if it is equivalent
equal(X,Y) :- sort(X,X1), sort(Y,Y1), X1 == Y1.
%find the length of the lists
total_length([],0).
total_length([_|Xs],L) :- total_length(Xs,M), L is M+1.
%storing length of lists and possible use of a decrement here to decrement the length...but don't understand how
storing(M,N) :- total_length(L,L_length), total_length(N,N_length), L_length is N_length, answer(L_length,N_length).
%Check for row equivalence...again, trying to find a way to decrement for the recursion, but unsure how to do it
sublist_check(Ra,Rb) :- storing(Ra,Rb), nth0(X,Ra,R1), nth0(Y,Rb,R2), equal(R1,R2), sublist_check(Ra,Rb).
假设输入是:
sublist_check([["A"],[],[]], [[],["A"],[]]). -->
false.
sublist_check([["A"],["B","C"],["B","C"]],[["A"],["C","B"],["C","B"]]). -->
true.
我认为我的问题是我需要找到一种方法来创建一个等于列表最大长度的变量并每次递减它,但是我 运行 进入了设置初始长度的错误sublist_check 回到原来的数字。
任何input/feedback都会很棒,非常感谢!
如果我没有正确理解你的问题,你想检查两个列表列表中相同位置的两个列表是否具有相同的元素。你可以这样做:
check([],_).
check([H|T],L):-
member(H,L),
check(T,L).
sublist_check([],[]).
sublist_check([H1|T1],[H2|T2]):-
check(H1,H2),
sublist_check(T1,T2).
?- sublist_check([["A"],["B","C"],["B","C"]],[["A"],["C","B"],["C","B"]]).
true
?- sublist_check([["A"],[],[]], [[],["A"],[]]).
false
这是 damianodamiano 答案的较短编码 (+1)
check1(S,L) :- maplist(member_(L), S).
sublist_check1(A,B) :- maplist(check1, A,B).
member_(L,H) :- member(H,L).
使用库(yall),更有吸引力:
check2(S,L) :- maplist({L}/[H]>>member(H,L), S).
sublist_check2(A,B) :- maplist(check2, A,B).
library(yall) 它并不孤单...
之后
?- pack_install(lambda).
你可以
:- use_module(library(lambda)).
check3(S,L) :- maplist(\H^member(H,L),S).
sublist_check3(A,B) :- maplist(check3, A,B).
我目前正在开发一个 Prolog 程序,该程序将在获得一组作品后生成 CYK 解析 table。但是,我无法检查两行以查看它们是否相等。这是我目前所拥有的:
answer(X,X).
%Checks to see if it is equivalent
equal(X,Y) :- sort(X,X1), sort(Y,Y1), X1 == Y1.
%find the length of the lists
total_length([],0).
total_length([_|Xs],L) :- total_length(Xs,M), L is M+1.
%storing length of lists and possible use of a decrement here to decrement the length...but don't understand how
storing(M,N) :- total_length(L,L_length), total_length(N,N_length), L_length is N_length, answer(L_length,N_length).
%Check for row equivalence...again, trying to find a way to decrement for the recursion, but unsure how to do it
sublist_check(Ra,Rb) :- storing(Ra,Rb), nth0(X,Ra,R1), nth0(Y,Rb,R2), equal(R1,R2), sublist_check(Ra,Rb).
假设输入是:
sublist_check([["A"],[],[]], [[],["A"],[]]). -->
false.
sublist_check([["A"],["B","C"],["B","C"]],[["A"],["C","B"],["C","B"]]). -->
true.
我认为我的问题是我需要找到一种方法来创建一个等于列表最大长度的变量并每次递减它,但是我 运行 进入了设置初始长度的错误sublist_check 回到原来的数字。
任何input/feedback都会很棒,非常感谢!
如果我没有正确理解你的问题,你想检查两个列表列表中相同位置的两个列表是否具有相同的元素。你可以这样做:
check([],_).
check([H|T],L):-
member(H,L),
check(T,L).
sublist_check([],[]).
sublist_check([H1|T1],[H2|T2]):-
check(H1,H2),
sublist_check(T1,T2).
?- sublist_check([["A"],["B","C"],["B","C"]],[["A"],["C","B"],["C","B"]]).
true
?- sublist_check([["A"],[],[]], [[],["A"],[]]).
false
这是 damianodamiano 答案的较短编码 (+1)
check1(S,L) :- maplist(member_(L), S).
sublist_check1(A,B) :- maplist(check1, A,B).
member_(L,H) :- member(H,L).
使用库(yall),更有吸引力:
check2(S,L) :- maplist({L}/[H]>>member(H,L), S).
sublist_check2(A,B) :- maplist(check2, A,B).
library(yall) 它并不孤单... 之后
?- pack_install(lambda).
你可以
:- use_module(library(lambda)).
check3(S,L) :- maplist(\H^member(H,L),S).
sublist_check3(A,B) :- maplist(check3, A,B).