When writing a purely relational prolog program, is it okay to use a carefully placed clipping?

I am trying to write my relational prolog program that manages a key, a value store. The source code is taken from some slide slides that I found on the Internet ( http://people.eng.unimelb.edu.au/pstuckey/book/course.html - see: using data structure slides).

newdic([]).
addkey(D0,K,I,D) :- D = [p(K,I)|D0].
delkey([],_,[]).
delkey([p(K,_)|D],K,D).
delkey([p(K0,I)|D0],K,[p(K0,I)|D]) :-
    dif(K, K0), delkey(D0,K,D).

This code allows you to add more than one value with the same key - and that’s good. However, it also adds the same key-value pair twice, for example.

?- newdic(D), addkey(D, a, 1, D2), addkey(D2, a, 1, D3), lookup(D3, a, X).
D = [],
D2 = [p(a, 1)],
D3 = [p(a, 1), p(a, 1)],
X = 1 

D3 includes p (a, 1) twice.

, ; , backtracking addkey, .

- , , .

newdic([]).
addkey(D0,K,I,D0) :- lookup(D0, K, I), !.   % if the key already do nothing
addkey(D0,K,I,D) :- D = [p(K,I)|D0].
delkey([],_,[]).
delkey([p(K,_)|D],K,D).
delkey([p(K0,I)|D0],K,[p(K0,I)|D]) :-
    dif(K, K0), delkey(D0,K,D).

:

?- newdic(D), addkey(D, a, 1, D2), addkey(D2, a, 1, D3), lookup(D3, a, X).
D = [],
D2 = D3, D3 = [p(a, 1)],
X = 1.

, - .

,

Daniel

: : , :

?- newdic(D), addkey(D, a, 1, D2), addkey(D2, a, 1, D3), addkey(D3, a, 2, D4), lookup(D4, a, X).
D = [],
D2 = D3, D3 = [p(a, 1)],
D4 = [p(a, 2), p(a, 1)],
X = 2 ;
D = [],
D2 = D3, D3 = [p(a, 1)],
D4 = [p(a, 2), p(a, 1)],
X = 1.
+4
2

SWI Prolog -. , , , - .

, addkey/4 :

addkey([], K, V, [p(K,V)]).             % Add to empty dict
addkey([p(K,V)|T], K, _, [p(K,V)|T]).   % Don't add
addkey([p(K,V)|T], Kadd, Vadd, [p(K,V)|TK]) :-
    dif(Kadd, K),
    addkey(T, Kadd, Vadd, TK).

, . , ( , -). -. , , , dif/2, dif/2.:)

+3

if-then-else cut:

addkey(D0,K,I,D0) :-
  ( lookup(D0, K, I) ->
    D = D0 % if the key already [exists] do nothing
  ; D = [p(K,I)|D0] ).
0

Source: https://habr.com/ru/post/1690233/


All Articles