0

我是 c++ 人,我对 prolog 完全陌生。我正在使用 sicstus prolog。

我遇到了如下需求:

假设我有一个变量

A={0,1,2,3}
B={-2,-1,0,1,2,3,4,5}

我有哈希之类的东西

0-{3}
1-{4}

现在我需要使用此哈希过滤 A 和 B 的值,以便在操作后:

A={0,1}
B={3,4}

逻辑是来自 A 的值将与散列的键匹配

如果键存在,则检查值。如果值存在于 B 中,则保留 A 中的值。否则应该删除值。以同样的方式对 B 进行处理,散列中的值应该在 A 中搜索,如果不存在,则应该在 B 中删除。对 B 意味着完全相反的方式。

有人可以帮忙吗?

4

2 回答 2

1

我建议您使用列表来保存 A 和 B 的键和值,并使用Key-Value对列表来保存您的哈希图。这样您就可以使用内置的辅助谓词include/3memberchk/2满足您的需求。

然后你可以编写一个过滤A和B项目的程序:

filter(A, B, Hash, FA, FB):-
  include(filterkey(B, Hash), A, FA),
  include(filtervalue(A, Hash), B, FB).

filterkey(B, Hash, Item):-
  memberchk(Item-Value, Hash),
  memberchk(Value, B).

filtervalue(A, Hash, Value):-
  memberchk(Item-Value, Hash),
  memberchk(Item, A).

说如果你有

A=[0,1,2,3]
B=[-2,-1,0,1,2,3,4,5]
Hash=[0-3, 1-4]

然后:

?- A=[0,1,2,3], B=[-2,-1,0,1,2,3,4,5], Hash=[0-3, 1-4], filter(A, B,Hash, FA, FB).
Hash = [0-3, 1-4],
FA = [0, 1],
FB = [3, 4].
于 2013-02-21T13:27:02.010 回答
0

很抱歉,我没有 Sicstus 可供测试,然后我可能会完全偏离轨道,但您正在处理一种非常特殊的变量。考虑

?- write_canonical({1,2,3,4}).
{}(','(1,','(2,','(3,4))))

?- {1,2,3,4}={A}.
A = (1, 2, 3, 4).

大括号实际上只是元组的一个特殊名称,AFAIK 被用作在 DSL(域特定语言)中引入可读数据的句法设备,例如库中的约束clpqr)。

我的意思是或者

  • 您对任务使用了错误的表示形式(gusbro 解决了这个问题,+1)
  • 您正在搜索 Sicstus 中不可用的 clp 约束扩展(过滤?)。但是,这个问题应该以更好的方式重新表述。

无论如何,如果添加例如,您可以在不更改程序的情况下调整 gusbro 的答案,

member_set(E, {','(E,_)}).
member_set(E, {','(_,T)}) :- member_set(E, {T}).
member_set(E, {E}).

替换memberchk。include/3 也必须重写,但这并不容易。否则,转换谓词

set_list({','(A,B)}, [A|R]) :- set_list({B}, R), !.
set_list({E}, [E]).
set_list({}, []).

可能很方便:

?- set_list(S,[1,2,3]).
S = {1, 2, 3}.

?- set_list({1,2,3},L).
L = [1, 2, 3].
于 2013-02-21T15:35:49.257 回答