Prolog:消除查询中的重复 [英] Prolog: eliminate repetitions in query

查看:65
本文介绍了Prolog:消除查询中的重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试编写一个简单的代码,它的行为方式如下:

I've been trying to write a simple code, that would behave in this manner:

| ?- hasCoppiesOf(X,[a,b,a,b,a,b,a,b]).
X = [a,b] ? ;
X = [a,b,a,b] ? ;
X = [a,b,a,b,a,b,a,b] ? ;

还有

| ?- hasCoppiesOf([a,b,a,b,a,b,a,b], X).    
X = [] ? ;    
X = [a,b,a,b,a,b,a,b] ? ;    
X = [a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b] ? ;    
X = ...

这个愿望导致了下一段代码:

This desire resulted in next piece of code:

hasCoppiesOf(A,[]).


hasCoppiesOf([H1|T1], [H1|T2]) :-
  append(T1, [H1], X),
  hasCoppiesOf([H1|T1], X, T2).


hasCoppiesOf(A, A, B) :-
  hasCoppiesOf(A, B).

hasCoppiesOf(A, [H1|T1], [H1|T2]) :-
  append(T1, [H1], X),
  hasCoppiesOf(A, X, T2).

它给了我我想要的第二个查询,但是,第一个结果是:

And it gives me what I want on the second query, however, the first results in:

?- hasCoppiesOf(X,[a,b,a,b,a,b,a,b]).
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b] ;

它似乎工作正常,但重复相同的答案让我感到困扰.这可能是一个简单的错误,但有没有办法使输出更漂亮?老实说,这是一个谜,为什么 Prolog 将两个相同的数组视为不同的答案.或者可能只是我的系统有问题?

It seems to be working fine, but that repetition of the same answers bothers me. It's, probably, a simple mistake, but is there a way to make the output prettier? And honestly, that a mystery, why Prolog treats two identical arrays as different answers. Or maybe it's just something wrong with my system?

评论中人的温柔指导帮助我解决了这个问题.但是,如果这个问题会读到想要解决完全相同问题的人 - 代码不能很好地工作,我很抱歉.

The gentle guidance of the person in the comments helped me to solve this issue. However, if this question will be reading the person who wants to solve exactly the same problem - code not really working well, my apologies.

推荐答案

我认为你只是让你的谓词比它需要的更复杂,可能只是想多了.一个给定的解决方案可能会通过逻辑在多个路径上取得成功.

I think you just made your predicate more complex than it needs to be, probably just overthinking it. A given solution may succeed in multiple paths through the logic.

您可以在没有 append/3 的情况下通过对齐列表的前端并保持原始列表在重复时重置"来做到这一点:

You can do this without append/3 by aligning the front end of the lists and keep the original list to "reset" on repeats:

% Empty list base cases
dups_list([], []).
dups_list([_|_], []).

% Main predicate, calling aux predicate
dups_list(L, Ls) :-
    dups_list(L, L, Ls).

% Recursive auxiliary predicate
dups_list([], [_|_], []).
dups_list([], [X|Xs], [X|Ls]) :-
    dups_list(Xs, [X|Xs], Ls).
dups_list([X|Xs], L, [X|Ls]) :-
    dups_list(Xs, L, Ls).

以下是一些结果:

| ?- dups_list(X,[a,b,a,b,a,b,a,b]).

X = [a,b] ? a

X = [a,b,a,b]

X = [a,b,a,b,a,b,a,b]

no
| ?- dups_list([a,b,a,b,a,b,a,b], X).

X = [] ? ;

X = [a,b,a,b,a,b,a,b] ? ;

X = [a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b] ? ;

X = [a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b] ?
...
| ?- dups_list(A, B).

A = []
B = [] ? ;

A = [_|_]
B = [] ? ;

A = [C]
B = [C] ? ;

A = [C]
B = [C,C] ? ;

A = [C,D]
B = [C,D] ? ;

A = [C]
B = [C,C,C] ? ;

A = [C,D,E]
B = [C,D,E] ? ;
...

可能有一种方法可以稍微简化解决方案,但我还没有足够的经验来确定是否是这种情况.

There may be a way to simplify the solution just a bit more, but I haven't played with it enough to determine if that's the case.

这篇关于Prolog:消除查询中的重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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