evs/2 — toate valuările pe o mulțime de variabile
Definiți un predicat evs/2 astfel încât, pentru orice listă de variabile S, avem că pentru orice Es, evs(S, Es) este adevărat exact atunci când Es este lista evaluărilor definite pe S.
?- evs([c, b], Es).
Es = [[(c, 0), (b, 0)], [(c, 1), (b, 0)], [(c, 0), (b, 1)], [(c, 1), (b, 1)]]
Hint: pentru
nvariabile, vrem2ⁿevaluări. Generează mai întâi toate tuplurile binare de lungimen(cucartesian_productșirepeat), apoi asociază fiecare tuplu variabilelor prinzip/3.
Te-ai blocat?
editor
soluție
cartesian_product([], _, [_], []) :- !.
cartesian_product([], L1, [_ | T2], R) :-
cartesian_product(L1, L1, T2, R).
cartesian_product([H1 | T1], L1, [H2 | T2], [HR | TR]) :-
append(H1, H2, HR),
cartesian_product(T1, L1, [H2 | T2], TR).
cartesian_product(L1, L2, R) :-
cartesian_product(L1, L1, L2, R).
repeat(L, 1, L) :- !.
repeat(L, N, Result) :-
cartesian_product(L, [[0], [1]], TempResult),
NewN is N - 1,
repeat(TempResult, NewN, Result).
repeat(RepNumber, Result) :-
repeat([[0], [1]], RepNumber, Result).
zip([], _, []) :- !.
zip(_, [], []) :- !.
zip([H1 | T1], [H2 | T2], [(H1, H2) | TR]) :-
zip(T1, T2, TR).
ziplist(_, [], []) :- !.
ziplist(L, [H | T], [HR | TR]) :-
zip(L, H, HR),
ziplist(L, T, TR).
evs(Vars, Es) :-
length(Vars, Length),
repeat(Length, AllEvals),
ziplist(Vars, AllEvals, Es).
?-
Tastează o interogare (ex. father_of(sandra, X).) și apasă Enter — sau apasă pe un caz de test de mai jos.
Cazuri de test (1 — apasă pe unul ca să îl rulezi, sau Verifică pentru toate)
?
evs([c, b], Es).
așteptat: Es = [[(c,0),(b,0)],[(c,1),(b,0)],[(c,0),(b,1)],[(c,1),(b,1)]]