如何检查元素是否不在列表中,如果不在,则插入它

时间:2016-05-19 14:36:29

标签: prolog

我希望,给定一个由AB元素([ab,bc,cd])组成的列表,检查某个给定元素是否已经在列表中(我将返回),如果不是,则添加任何“A”或“B”元素尚未出现在输出列表中。

我还没有真正找到任何“简单”的答案让我理解(比如,我发现了一个带有映射和我以前从未使用过的东西)。

因此输出列表只需要[a,b,c,d]

编辑:我正在尝试做的是,我这样被调用:

enumerate([a-b,b-c,c-d], EnumNodes, EnumArcs)

我必须返回两个列表。第一个给出节点(具有这种特定形式:

[enum(1,a),enum(2,b),enum(3,c),enum(4,d)]

和第二个给出所述节点之间的弧(连接)。

所以我在“知道”如何计算和返回列表中的项目的部分,但我不知道以下内容:

- 如何在列表中插入唯一的元素

- 首先检查列表中是否有“A”,如果没有插入,然后检查列表中是否有“B”,如果没有,请插入(原因我不知道,我可以'有一种调用规则的方法,一旦完成,两次,每个元素一次,递归的每一步,不会出错#/ p>

1 个答案:

答案 0 :(得分:1)

您在寻找这样的条款吗?

% ensure(ELEMENT, LIST_IN, LIST_OUT)

% If X is already a member of L, then the result is L
ensure(X, L, L) :-
    member(X, L), !.

% If not, the result is X appended to L
ensure(X, L, [X | L]).

使用:

1 ?- ensure(1, [1,2,3], O).
O = [1, 2, 3].

2 ?- ensure(2, [1,3], O).
O = [2, 1, 3].

认为这就是你要找的东西......

% enumerate(CONNECTIONS_IN, NODES_OUT, ARCS_OUT)

enumerate(C, N, A) :-
    enum_nodes(C, [], N, 1),
    create_arcs(C, N, A).

% enum_nodes(CONNECTIONS_IN, NODES_IN, NODES_OUT, START_ID) 
% Fills up NODES_OUT with enums. New IDs start at START_ID...

enum_nodes([], N, N, _).
enum_nodes([A-B | T], N, NOUT, ID) :-
    ensure_node(A, N, NTMP1, ID, ID1),
    ensure_node(B, NTMP1, NTMP2, ID1, ID2),
    enum_nodes(T, NTMP2, NOUT, ID2).

% ensure_node(NODE, NODES_IN, NODES_OUT, ID_IN, ID_OUT)
% Adds enum(ID_IN, NODE) to NODES_IN to produce NODES_OUT if NODE does not already exist in NODES_IN

ensure_node(NODE, NODES_IN, NODES_IN, ID, ID) :-
    member(enum(_, NODE), NODES_IN), !.

ensure_node(NODE, NODES_IN, [enum(ID_IN, NODE) | NODES_IN], ID_IN, ID_OUT) :-
    ID_OUT is ID_IN + 1.

% create_arcs(CONNECTIONS_IN, NODES_IN, ARCS_OUT).  
% Create arcs - makes a list of arc(NODE_ID_1, NODE_ID_2)...

create_arcs([], _, []).
create_arcs([A-B | T], NODES, [arc(NODE_ID_A, NODE_ID_B) | TARCS]) :-
    member(enum(NODE_ID_A, A), NODES),
    member(enum(NODE_ID_B, B), NODES),
    create_arcs(T, NODES, TARCS).

示例输出:

1 ?- enumerate([a-b, c-d, d-a], N, A).
N = [enum(4, d), enum(3, c), enum(2, b), enum(1, a)],
A = [arc(1, 2), arc(3, 4), arc(4, 1)] .

如果您执行trace,则可以看到它正常工作......

2 ?- trace.
true.

[trace] 2 ?- enumerate([a-b, c-d, d-a], N, A).
   Call: (6) enumerate([a-b, c-d, d-a], _G2634, _G2635) ? creep
   Call: (7) enum_nodes([a-b, c-d, d-a], [], _G2634, 1) ? creep
   Call: (8) ensure_node(a, [], _G2740, 1, _G2742) ? creep
   Call: (9) lists:member(enum(_G2731, a), []) ? creep
   Fail: (9) lists:member(enum(_G2731, a), []) ? creep
   Redo: (8) ensure_node(a, [], _G2740, 1, _G2742) ? creep
   Call: (9) _G2747 is 1+1 ? creep
   Exit: (9) 2 is 1+1 ? creep
   Exit: (8) ensure_node(a, [], [enum(1, a)], 1, 2) ? creep
   Call: (8) ensure_node(b, [enum(1, a)], _G2749, 2, _G2751) ? creep
   Call: (9) lists:member(enum(_G2740, b), [enum(1, a)]) ? creep
   Fail: (9) lists:member(enum(_G2740, b), [enum(1, a)]) ? creep
   Redo: (8) ensure_node(b, [enum(1, a)], _G2749, 2, _G2751) ? creep
   Call: (9) _G2756 is 2+1 ? creep
   Exit: (9) 3 is 2+1 ? creep
   Exit: (8) ensure_node(b, [enum(1, a)], [enum(2, b), enum(1, a)], 2, 3) ? creep
   Call: (8) enum_nodes([c-d, d-a], [enum(2, b), enum(1, a)], _G2634, 3) ? creep
   Call: (9) ensure_node(c, [enum(2, b), enum(1, a)], _G2758, 3, _G2760) ? creep
   Call: (10) lists:member(enum(_G2749, c), [enum(2, b), enum(1, a)]) ? creep
   Fail: (10) lists:member(enum(_G2749, c), [enum(2, b), enum(1, a)]) ? creep
   Redo: (9) ensure_node(c, [enum(2, b), enum(1, a)], _G2758, 3, _G2760) ? creep
   Call: (10) _G2765 is 3+1 ? creep
   Exit: (10) 4 is 3+1 ? creep
   Exit: (9) ensure_node(c, [enum(2, b), enum(1, a)], [enum(3, c), enum(2, b), enum(1, a)], 3, 4) ? creep
   Call: (9) ensure_node(d, [enum(3, c), enum(2, b), enum(1, a)], _G2767, 4, _G2769) ? creep
   Call: (10) lists:member(enum(_G2758, d), [enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Fail: (10) lists:member(enum(_G2758, d), [enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Redo: (9) ensure_node(d, [enum(3, c), enum(2, b), enum(1, a)], _G2767, 4, _G2769) ? creep
   Call: (10) _G2774 is 4+1 ? creep
   Exit: (10) 5 is 4+1 ? creep
   Exit: (9) ensure_node(d, [enum(3, c), enum(2, b), enum(1, a)], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], 4, 5) ? creep
   Call: (9) enum_nodes([d-a], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], _G2634, 5) ? creep
   Call: (10) ensure_node(d, [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], _G2776, 5, _G2778) ? creep
   Call: (11) lists:member(enum(_G2767, d), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Exit: (11) lists:member(enum(4, d), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Exit: (10) ensure_node(d, [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], 5, 5) ? creep
   Call: (10) ensure_node(a, [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], _G2779, 5, _G2781) ? creep
   Call: (11) lists:member(enum(_G2770, a), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Exit: (11) lists:member(enum(1, a), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Exit: (10) ensure_node(a, [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], 5, 5) ? creep
   Call: (10) enum_nodes([], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], _G2634, 5) ? creep
   Exit: (10) enum_nodes([], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], 5) ? creep
   Exit: (9) enum_nodes([d-a], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], 5) ? creep
   Exit: (8) enum_nodes([c-d, d-a], [enum(2, b), enum(1, a)], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], 3) ? creep
   Exit: (7) enum_nodes([a-b, c-d, d-a], [], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], 1) ? creep
   Call: (7) create_arcs([a-b, c-d, d-a], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], _G2635) ? creep
   Call: (8) lists:member(enum(_G2776, a), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Exit: (8) lists:member(enum(1, a), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Call: (8) lists:member(enum(_G2777, b), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Exit: (8) lists:member(enum(2, b), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Call: (8) create_arcs([c-d, d-a], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], _G2774) ? creep
   Call: (9) lists:member(enum(_G2788, c), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Exit: (9) lists:member(enum(3, c), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Call: (9) lists:member(enum(_G2789, d), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Exit: (9) lists:member(enum(4, d), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Call: (9) create_arcs([d-a], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], _G2786) ? creep
   Call: (10) lists:member(enum(_G2800, d), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Exit: (10) lists:member(enum(4, d), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Call: (10) lists:member(enum(_G2801, a), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Exit: (10) lists:member(enum(1, a), [enum(4, d), enum(3, c), enum(2, b), enum(1, a)]) ? creep
   Call: (10) create_arcs([], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], _G2798) ? creep
   Exit: (10) create_arcs([], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], []) ? creep
   Exit: (9) create_arcs([d-a], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], [arc(4, 1)]) ? creep
   Exit: (8) create_arcs([c-d, d-a], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], [arc(3, 4), arc(4, 1)]) ? creep
   Exit: (7) create_arcs([a-b, c-d, d-a], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], [arc(1, 2), arc(3, 4), arc(4, 1)]) ? creep
   Exit: (6) enumerate([a-b, c-d, d-a], [enum(4, d), enum(3, c), enum(2, b), enum(1, a)], [arc(1, 2), arc(3, 4), arc(4, 1)]) ? creep
N = [enum(4, d), enum(3, c), enum(2, b), enum(1, a)],
A = [arc(1, 2), arc(3, 4), arc(4, 1)] .