Create a N x N matrix in Prolog (using lists?) - list

I want a have a matrix of size N x N in SWI-Prolog. A possible solution could be to create a list of N lists of size N, but now sure how to code this in Prolog.

length_list(N, L) :-
length(L, N).
n_matrix(N, Xss) :-
length(Xss, N),
maplist(length_list(N),Xss).
maplist(_, []).
maplist(C, [X|Xs]) :-
call(C,X),
maplist(C, Xs).
To avoid the awkward auxiliary definition, we might use library(lambda):
n_matrix(N, Xss) :-
length(Xss, N),
maplist(N+\Xs^length(Xs,N),Xss).

Related

Longest subsequence in Prolog

I want to implement a predicate P(Xs,Ys,Zs) where Xs,Ys,Zs are lists.
I'm new in Prolog and I can't find a way to get to the longest sequence in Xs (example. Xs = ['b','b','A','A','A','A','b','b']) which is included to Ys (for example Ys = ['A','A','A','A','c','A','A','A','A']) without crossing- an even number of times. Maybe someone already wrote this code ore some one can say me how can I start. Thanks for helps.
explanation of teacher.
longest_subsequence(List, Part, Subsequence):-
longest_subsequence_(List, Part, [], Subsequence).
longest_subsequence_(Xs, Ys, CurrentSubsequence, LongestSubsequence):-
append(CurrentSubsequence, Ys, NextSubsequence),
divide_list(Xs, [_LeftYs, NextSubsequence, _RightYs]), !,
longest_subsequence_(Xs, Ys, NextSubsequence, LongestSubsequence).
longest_subsequence_(_Xs, _Ys, LongestSubsequence, LongestSubsequence).
okey i did.
main_task(Xs, Ys, Zs) :-
atom_chars(Xs, Xl),
atom_chars(Ys, Yl),
retractall(record(_, _)),
assert(record(0, [])),
process(Xl, Yl, Zl),
atom_chars(Zs, Zl).
process(Xl, Yl, _) :-
get_sublist(Xl, Zl),
length(Zl, L),
record(MaxL, _),
L > MaxL,
get_index(Yl, Zl, Il),
test_even(Il),
test_intersect(Il, L),
retractall(record(_, _)),
assert(record(L, Zl)),
fail.
process(_, _, Zl) :-
record(_, Zl).
get_sublist(L1, L2) :-
get_tail(L1, L3),
get_head(L3, L2).
get_tail(L, L).
get_tail([_|T], L) :-
get_tail(T, L).
get_head([H|T1], [H|T2]) :-
get_head(T1, T2).
get_head(_, []).
get_index(Yl, Zl, Il) :-
get_index(Yl, Zl, Il, 0).
get_index([], _, [], _).
get_index([Yh|Yt], Zl, [I|It], I) :-
get_head([Yh|Yt], Zl),
!,
I1 is I + 1,
get_index(Yt, Zl, It, I1).
get_index([_|Yt], Zl, Il, I) :-
I1 is I + 1,
get_index(Yt, Zl, Il, I1).
test_even(Il) :-
length(Il, L),
L > 0,
L mod 2 =:= 0.
test_intersect([_], _).
test_intersect([X,Y|T], L) :-
Y - X >= L,
test_intersect([Y|T], L).
All lines in the list at the symbols on working with lists
Initialize the dynamic database - will be stored in it, and its maximum line length
enumerates all of the substring (sublists) from X. Bust goes double "pruning" - first place in a list of cut off the front, then from behind.
Check the length of the resulting string, if we already have a long, immediately leave for the continuation of busting
We consider a list of indexes in the occurrence of a Y, then there is every element of the list - a position in the Y, from which it includes Z.
Check the parity - just consider the length of the list of indexes, chёtnaya length - an even number of entries. And we need to check that it is greater than zero.
Check the intersection - you need to check the difference between two adjacent elements of the list of indexes, the difference should always be greater than the length Z.
If all checks are made, there is a dynamic database updates - current list Z is stored as the maximum
At the end it is a forced failure, it is rolled back to the fork in paragraph 3) and the continued search.
Note: If any check is not performed, the failure of this test is immediately rolled back to the fork in paragraph 3) and the continued search.
When the bust comes to an end, performed a second rule predicate process, it simply selects the last spicok Z in the base.
At the end of the list Z is converted back to a string
A naive approach is the following:
longest_subsequence(Xs,Ys,Zs) :-
longest_subsequence(Xs,Ys,Ys,0,[],Zs).
longest_subsequence([X|Xs],Y0,[Y|Ys],N0,Z0,Z) :-
try_seq([X|Xs],[Y|Ys],Nc,Zc),
(Nc > N0
-> longest_subsequence([X|Xs],Y0,Ys,Nc,Zc,Z)
; longest_subsequence([X|Xs],Y0,Ys,N0,Z0,Z)
).
longest_subsequence([_|Xs],Y0,[],N0,Z0,Z) :-
longest_subsequence(Xs,Y0,Y0,N0,Z0,Z).
longest_subsequence([],_,_,_,Z,Z).
try_seq([H|TA],[H|TB],N,[H|TC]) :-
!,
try_seq(TA,TB,N1,TC),
N is N1+1.
try_seq(_,_,0,[]).
here a predicate try_seq/3 aims to match as much as possible (generate the longest common subsequence) starting from the beginning of the list.
The problem is that this is a computationally expensive approach: it will have a time complexity O(m n p) with n the length of the first list, m the length of the second list and p the minimum length of the two lists.
Calling this with your example gives:
?- longest_subsequence([b,b,a,a,a],[a,a,a,c,a,a,a],Zs).
Zs = [a, a, a] ;
false.
You can make the algorithm more efficient using back-referencing, this is more or less based on the Knuth-Morris-Pratt-algorithm.
When approaching a problem, first try: divide and conquer.
When we have a list_subsequence(+List, ?Subsequence) predicate
list_subsequence([H|T], S) :-
list_subsequence(H, T, S, _).
list_subsequence([H|T], S) :-
list_subsequence(H, T, _, R),
list_subsequence(R, S).
list_subsequence(H, [H|T], [H|S], R) :- !, list_subsequence(H, T, S, R).
list_subsequence(H, R, [H], R).
we can call for library(aggregate) help:
longest_subsequence(Seq, Rep, Longest) :-
aggregate(max(L, Sub), N^(
list_subsequence(Seq, Sub),
aggregate(count, list_subsequence(Rep, Sub), N),
N mod 2 =:= 0,
length(Sub, L)
), max(_, Longest)).
edit: more library support available
A recently added library helps:
longest_subsequence_(Seq, Rep, Longest) :-
order_by([desc(L)], filter_subsequence(Seq, Rep, Longest, L)), !.
where filter_subsequence/4 is simply the goal of the outer aggregate:
filter_subsequence(Seq, Rep, Sub, L) :-
list_subsequence(Seq, Sub),
aggregate(count, list_subsequence(Rep, Sub), N),
N mod 2 =:= 0,
length(Sub, L).

Prolog: how to transpose non-rectangular matrices by padding

As of right now, I use the following code for transposing rectangular matrices.
trans(L,[Head|Tail]) :-
list_first(L,Head,A),
trans(A,Tail).
trans(Empty,[]) :-
empty(Empty).
empty([[]|Tail]) :-
empty(Tail).
empty([[]]).
list_first([[Head|A]|Rest],[Head|Heads],[A|As]) :-
list_first(Rest,Heads,As).
list_first([],[],[]).
How can I make it work with "jagged" list of lists like [[a,b,c],[1,2]], as used below, too?
Sample query:
?- trans([[a,b,c],[1,2]], T).
false. % desired answer: T = [[a,1],[b,2],[c,[]]
I would stay with some 'reusable' utilities, preprocessing the Lists and ensure all have the same length:
lists_length_max(ListS, LenS, MaxLen) :-
maplist(length, ListS, LenS),
max_list(LenS, MaxLen).
list_padding(MaxLen, ElemPad, List, Len, Padded) :-
LenTail is MaxLen - Len,
length(Tail, LenTail),
maplist(=(ElemPad), Tail),
append(List, Tail, Padded).
trans_padding(ListS, Trans) :-
trans_padding(ListS, Trans, []).
trans_padding(ListS, Trans, PadElem) :-
lists_length_max(ListS, LenS, MaxLen),
maplist(list_padding(MaxLen, PadElem), ListS, LenS, Padded),
trans(Padded, Trans).
now, trans_padding/2 should be called instead of trans/2
Here's another variation:
row([], [_|_], [], []).
row([[]|Rs], A, NewRs, [[]|Cs]) :-
row(Rs, A, NewRs, Cs).
row([[X|Xs]|Rs], A, [Xs|NewRs], [X|Cs]) :-
row(Rs, [X|A], NewRs, Cs).
transpose(Rows, [T|Ts]) :-
row(Rows, [], Rest, T),
transpose(Rest, Ts).
transpose(Empty, []) :-
maplist(=([]), Empty).
transpose operates a row at a time. The row predicate uses an auxiliary argument (the third one) to ensure that it terminates without generating phantom rows that are all empty elements. The call to maplist(=([]), Empty) is a short-hand for the predicate empty/1 defined in the question.

How to implement a fill method in prolog

I'm rather new to prolog and I am trying to implement a method called fill
which has the structure
fill(4,1,X).
X = [1,1,1,1]
However I not sure how to implement this because I know prolog do not allow indexed list. So how am I suppose to return an array.
fill(N, E, Xs) :-
length(Xs, N), % Xs is a list of length N
maplist(=(E), Xs). % all elements in Xs are equal to E
%fill(+N,+X,-L) element X is replicated N times
fill(0,_,[]).
fill(N,X,[X|Xs]) :- N > 0, N1 is N-1, fill(N1,X,Xs).
findall/3 it's the swissknife for list building:
fill(N, E, Xs) :- findall(E, between(1, N, _), Xs).

Assigning values to matrix(a list of lists) in Prolog

I want to have a N x N matrix in SWI-Prolog with values of every element assigned in the range 1..9. Here's my code
:- use_module(library(clpfd)).
n_matrix(N, Rows) :-
length(Rows, N),
Rows ins 1..9,
maplist(length_(N), Rows).
length_(L, Ls) :- length(Ls, L).
It gives the following error:
1 ?- n_matrix(4,R).
ERROR: Type error:integer' expected, found [_G2363,_G2366,_G2369,_G2372]'
Of course, the domain assignment Xs ins 1..9, should be applied on each Row in Rows, while you're applying to the 'matrix'... I would write
n_matrix(N, Rows) :-
length(Rows, N),
maplist(row(N), Rows).
row(N, Row) :-
length(Row, N),
Row ins 1..9.
As an alternative - less readable imo -
n_matrix(N, Rows) :-
bagof(Row, C^(between(1, N, C), length(Row, N), Row ins 1..9), Rows).

Prolog: find all numbers of unique digits that can be formed from a list of digits

The best thing I could come up with so far is this function:
numberFromList([X], X) :-
digit(X), !.
numberFromList(List, N) :-
member(X, List),
delete(List, X, LX),
numberFromList(LX, NX),
N is NX * 10 + X.
where digit/1 is a function verifying if an atom is a decimal digit.
The numberFromList(List, N) finds all the numbers that can be formed with all digits from List.
E.g. [2, 3] -> 23, 32.
but I want to get this result: [2, 3] -> 2, 3, 23, 32
I spent a lot of hours thinking about this and I suspect you might use something like append(L, _, List) at some point to get lists of lesser length.
I would appreciate any contribution.
You are missing case when you skip digit from list.
numberFromList([X], X) :-
digit(X), !.
numberFromList(List, N) :-
member(X, List),
delete(List, X, LX),
numberFromList(LX, NX),
( % use X
N is NX * 10 + X
; % skip X
N = NX
).
BTW, as #Roland Illig mentioned there is select(X, List, LX) to replace member(X, List), delete(List, X, LX)
The predicate unique/3 generates all lists of length up to MaxLen consisting of symbols from Symbols. The generated lists are stored in L, once at a time.
unique(MaxLen, Symbols, L) :-
between(0, MaxLen, Len),
length(L, Len),
unique(Symbols, L).
The helper predicate for generating the lists.
unique(_, []).
unique(Set, [H|R]) :-
select(H, Set, ReducedSet),
unique(ReducedSet, R).
A simple program for demonstrating the above predicate:
main :-
unique(5, [2,3], L),
write(L), nl, fail.
Here's one way, using SWI-PROLOG built-ins for atomic_list_concat/2, atom_number/2 and select/3. Firstly, the entry point refers to an implementation using an initially empty accumulator:
numberFromList(L, N) :-
numberFromList(L, [], N).
The predicate numberFromList/3 either accumulates digits (unchecked) from the list, or not, leaving choicepoints:
numberFromList([_|Cs], Acc, N) :-
numberFromList(Cs, Acc, N).
numberFromList([C|Cs], Acc, N) :-
numberFromList(Cs, [C|Acc], N).
The final clause of numberFromList/3 permutes the accumulated list of digits and concatenates them into an atom, which is then converted to a number as required:
numberFromList([], [C|Cs], N) :-
permute([C|Cs], PermutedAcc),
atomic_list_concat(PermutedAcc, AN),
atom_number(AN, N).
Sometimes permute/2 (as defined manually below) may be available as a built-in, such as permutation/2. Here is a manual definition using select/3:
permute([], []).
permute([E|Es], [E0|PL]) :-
select(E0, [E|Es], Rem),
permute(Rem, PL).
If you want a list of all the results and don't want numberFromList/2 to backtrack itself, you could wrap the call to numberFromList/3 (with the empty accumulator in the first clause of numberFromList/2) in a findall/3 call.