gpt4 book ai didi

prolog - 一次性删除不正确的后续解决方案

转载 作者:行者123 更新时间:2023-12-04 02:11:40 25 4
gpt4 key购买 nike

我有一个谓词可以找到正确的解决方案,然后继续寻找不正确的解决方案。

?- data(D),data_threshold_nonredundantbumps(D,5,Bs),write(D).
[3,6,7,8,2,4,5,6,9,4,7,3]
D = [3, 6, 7, 8, 2, 4, 5, 6, 9|...],
Bs = [bump([11], [7]), bump([8, 9], [6, 9]), bump([2, 3, 4], [6, 7, 8])] ;
[3,6,7,8,2,4,5,6,9,4,7,3]
D = [3, 6, 7, 8, 2, 4, 5, 6, 9|...],
Bs = [bump([8, 9], [6, 9]), bump([2, 3, 4], [6, 7, 8])] ;
[3,6,7,8,2,4,5,6,9,4,7,3]
D = [3, 6, 7, 8, 2, 4, 5, 6, 9|...],
Bs = [bump([8], [6]), bump([2, 3, 4], [6, 7, 8])] ;
[3,6,7,8,2,4,5,6,9,4,7,3]
D = [3, 6, 7, 8, 2, 4, 5, 6, 9|...],
Bs = [bump([9], [9]), bump([2, 3, 4], [6, 7, 8])] ;
[3,6,7,8,2,4,5,6,9,4,7,3]
D = [3, 6, 7, 8, 2, 4, 5, 6, 9|...],
Bs = [bump([11], [7]), bump([2, 3, 4], [6, 7, 8])] ;
[3,6,7,8,2,4,5,6,9,4,7,3]
D = [3, 6, 7, 8, 2, 4, 5, 6, 9|...],
Bs = [bump([2, 3, 4], [6, 7, 8])] ;

等等

这个想法是它会找到数据中的所有非冗余凸起,其中凸起是 data 的连续子列表。高于 threshold , 返回 bump/2s 的有序(按大小)列表其中,bump/2 的第一个 arg 是来自数据的索引列表,第二个 arg 是值列表。所以 bump([2, 3, 4], [6, 7, 8])意味着在数据索引 2,3 和 4 大于 5,它们是 6,7,8。

如何添加条件以便找不到这些额外的解决方案? -不使用 once/1 .

如果我的代码可以以其他方式简化,请告诉我。它试图做的事情似乎有点复杂。

所以:

这是我的代码:
:-use_module(library(clpfd)).

fd_length(L, N) :-
N #>= 0,
fd_length(L, N, 0).

fd_length([], N, N0) :-
N #= N0.
fd_length([_|L], N, N0) :-
N1 is N0+1,
N #>= N1,
fd_length(L, N, N1).

equidistant_stride([],_).
equidistant_stride([Z|Zs],D) :-
foldl(equidistant_stride_(D),Zs,Z,_).

equidistant_stride_(D,Z1,Z0,Z1) :-
Z1 #= Z0+D.

consecutive_ascending_integers(Zs) :-
equidistant_stride(Zs,1).

consecutive_ascending_integers_from(Zs,Z0) :-
Zs = [Z0|_],
consecutive_ascending_integers(Zs).

bool01_t(1,true).
bool01_t(0,false).

if_(C_1,Then_0,Else_0) -->
{ call(C_1,Truth) },
{ functor(Truth,_,0) }, % safety check
( { Truth == true } -> phrase(Then_0)
; { Truth == false }, phrase(Else_0)
).

if_(If_1, Then_0, Else_0) :-
call(If_1, T),
( T == true -> call(Then_0)
; T == false -> call(Else_0)
; nonvar(T) -> throw(error(type_error(boolean,T),_))
; /* var(T) */ throw(error(instantiation_error,_))
).


#=<(X,Y,Truth) :- X #=< Y #<==> B, bool01_t(B,Truth).

#<( X,Y,Truth) :- X #< Y #<==> B, bool01_t(B,Truth).

#>( X,Y,Truth) :- X #> Y #<==> B, bool01_t(B,Truth).

#>=(X,Y,Truth) :- X #>= Y #<==> B, bool01_t(B,Truth).

tinclude(P_2,Xs,Zs) :-
list_tinclude_list(Xs,P_2,Zs).

list_tinclude_list([], _P_2,[]).
list_tinclude_list([i_v(E0,E1)|Es],P_2,Fs0) :-
if_(call(P_2,E1), Fs0 = [i_v(E0,E1)|Fs], Fs0 = Fs),
list_tinclude_list(Es,P_2,Fs).


tfilter(P_2,As,Bs) :-
tinclude(P_2,As,Bs).

%% =====================================================================
%% =====================================================================

data([5,6,7,8,3,2,6,7]).

list_index_element(L,I,E):-
nth1(I,L,E).

filter(Threshold,DataPairs,FilterdPairs):-
tfilter(#<(Threshold),DataPairs,FilterdPairs).

i_v_pair(I,V,i_v(I,V)).

data_indices_indicespairs(D,Is,Pairs):-
same_length(D,Is),
consecutive_ascending_integers_from(Is,1),
maplist(i_v_pair,Is,D,Pairs).

list_ascending(List,MinLength,MaxLength):-
Max in MinLength..MaxLength,
labeling([max(Max)],[Max]),
fd_length(List,Max),
consecutive_ascending_integers(List).

region_minlength_maxlength(Region,MinLength,MaxLength,All):-
list_ascending(Region,MinLength,MaxLength),
append(_Before,End,All),
append(Region,_End2,End).

data_threshold_bumpvalues_bumplocation(Data,Threshold,Bumpvalues,Bumplocation):-
length(Data,MaxBump),
data_indices_indicespairs(Data,_Is,Pairs),
filter(Threshold,Pairs,FilteredPairs),
maplist(i_v_pair,FilteredIndices,_FilteredValues,FilteredPairs),
%Test =test(FilteredIndexes,FilteredValues),
dif(Bumplocation,[]),
region_minlength_maxlength(Bumplocation,0,MaxBump,FilteredIndices),
maplist(list_index_element(Data), Bumplocation,Bumpvalues).


list_first_last([H|T],H,L):-
last(T,L).

listoflists_firsts_lasts(Listoflists,Firsts,Lasts):-
maplist(list_first_last,Listoflists,Firsts,Lasts).

%start is not between location1 and location2
start_location1_location2(Start,Location1,Location2) :-
#\( Location1 #=< Start,
Start #=< Location2).

bumplocation_notsublist_of_any_acs(Bumplocation,Acs):-
listoflists_firsts_lasts(Acs,Firsts,Lasts),
%the start of bumplocation can not be between the start of any Acs
Bumplocation =[Bumpstart|_],
maplist(start_location1_location2(Bumpstart),Firsts,Lasts).


loc_val_bump(Location,Value,bump(Location,Value)).

data_bumplocations_bumpvalues(Data,Bumplocations,Bumpvalues):-
maplist(list_index_element(Data),Bumplocations,Bumpvalues).

%this works but finds extra solutins so needs to be refined.
data_threshold_nonredundantbumps(Data,Threshold,Bumps):-
data_threshold_nonredundantbumps_ac(Data,Threshold,Nonredundantbumpslocations,[]),
maplist(data_bumplocations_bumpvalues(Data),Nonredundantbumpslocations,Nonredundantbumps),
maplist(loc_val_bump,Nonredundantbumpslocations,Nonredundantbumps,Bumps).

data_threshold_nonredundantbumps_ac(Data,Threshold,Nonredundantbumps,Ac0):-
bumplocation_notsublist_of_any_acs(Bumplocation,Ac0),
data_threshold_bumpvalues_bumplocation(Data,Threshold,_Bumpvalues,Bumplocation),
append([Bumplocation],Ac0,Ac1),
data_threshold_nonredundantbumps_ac(Data,Threshold,Nonredundantbumps,Ac1).

data_threshold_nonredundantbumps_ac(_Data,_Threshold,Ac0,Ac0).

最佳答案

我的印象是你有点想多了。 有一个简单的公式运行 超过阈值的数字,可以通过在列表的单次遍历中考虑从头到尾的元素来定义。特别是我们做不是 需要append/3这样做。

始终考虑使用 DCG 符号 ( ) 在 Prolog 中描述列表时。在这种情况下,决定如何最好地应用 DCG 需要一段时间的反射(reflection),因为我们正在描述两个列表:

  • 的列表运行 (连续元素超过阈值)
  • 在运行中,列表 指数 .

  • 然而,除了一些技巧和扩展之外,DCG 本质上只能让我们描述单个列表,而不是同时描述单独的列表。因此,我们拥有这种强大且可能非常合适的机制供我们使用,并且必须选择我们希望主要应用它的列表类型。

    在下面,我展示了一个使用 DCG 来描述 列表的解决方案。凹凸/1 术语,即我“专门”使用机制来描述上面提到的第一种列表,并使用另一个 DCG 来描述第二种列表,我通过 phrase/2 调用它。从第一个 DCG 中。
    data_threshold_bumps(Ds, T, Bs) :-
    phrase(bumps(Ds, 1, T), Bs).

    bumps([], _, _) --> [].
    bumps([D|Ds0], I0, T) -->
    { D #> T,
    phrase(bump(D, T, Ds0, Ds, I0, I), Bs) },
    [bump(Bs)],
    bumps(Ds, I, T).
    bumps([D|Ds0], I0, T) -->
    { D #=< T,
    I #= I0 + 1 },
    bumps(Ds0, I, T).


    bump(D, T, Ds0, Ds, I0, I) --> [I0-D],
    { I1 #= I0 + 1 },
    run(Ds0, Ds, T, I1, I).

    run([], [], _, I, I) --> [].
    run([D|Ds0], Ds, T, I0, I) --> [I0-D],
    { D #> T,
    I1 #= I0 + 1 },
    run(Ds0, Ds, T, I1, I).
    run([D|Ds0], [D|Ds0], T, I, I) -->
    { D #=< T }.

    示例查询和回答:

    ?- data_threshold_bumps([3,6,7,8,2,4,5,6,9,4,7,3], 5, Bs)。
    Bs = [凹凸([2-6, 3-7, 4-8]), 凹凸([8-6, 9-9]), 凹凸([11-7])] ;
    假的。

    请注意,这与您需要的数据表示形式并不完全相同,但将其转换为该表示形式很简单。

    以下是改进此解决方案的一些想法,从易到难:
  • 摆脱不必要的选择点,使用 if_/3 .
  • bumps//3 使用 DCG 表示法实际上有意义吗?和 run//5在上面的代码中?与常规谓词相比,在此处使用 DCG 的优点和缺点是什么?
  • 以不同的视角看待问题:你能扭转 DCG 视角吗?例如,如何描述实际的 数据用 DCG,而不是颠簸?
  • 在您发布的代码中追踪不需要的解决方案的来源。

  • 顺便说一句,要否定(可具体化的)CLP(FD) 约束,您需要使用 (#/\)/2表示连词。它不适用于 (,)/2 .

    关于prolog - 一次性删除不正确的后续解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38543599/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com