Is it possible with DCGs to extract some 2D list, such that it can be represented by a context free grammar
S -> [ A , B ]
A -> [0,0,0,0,0]
A -> NULL
B -> [1,1,1,1,1]
B -> NULL
for example:
[[0,0,0,0,0], [1,1,1,1,1]] is valid
[[1,1,1,1,1]] is valid, where A is NULL.
[[0,0,0,0,0]] is valid, where B is NULL.
I tried something like this
zeros --> [].
zeros --> [0,0,0,0,0].
ones --> [].
ones --> [1,1,1,1,1]
matrix --> [A, B],
{phrase(zeros, A)},
{phrase(ones, B)}.
But this is not going to work the way I wanted it to, because in this case, the "compiler" thought I want an empty list '[]' instead of NULL.
so [[], [1,1,1,1,1]] will work while [[1,1,1,1,1]] is not.
How do I approach this?
The problem is that once you write matrix --> [A, B], that rule will definitely generate a two-element list, no matter what A and B are.
So you want to alternatively generate one-element lists [A] or [B]. You could do this explicitly:
a --> [0, 0, 0, 0, 0].
b --> [1, 1, 1, 1, 1].
matrix -->
[A],
{ phrase(a, A) }.
matrix -->
[B],
{ phrase(b, B) }.
matrix -->
[A, B],
{ phrase(a, A) },
{ phrase(b, B) }.
This works:
?- phrase(matrix, Matrix).
Matrix = [[0, 0, 0, 0, 0]] ;
Matrix = [[1, 1, 1, 1, 1]] ;
Matrix = [[0, 0, 0, 0, 0], [1, 1, 1, 1, 1]].
But this is a lot of typing, and it's not very flexible if you want to extend it.
So let's try to generalize the fixed [A, B] bit. As a first step, we can use a list//1 DCG that just describes its own argument list:
list([]) -->
[].
list([X|Xs]) -->
[X],
list(Xs).
We can use this as follows:
?- phrase(list([a, b, c]), Xs).
Xs = [a, b, c].
And use it to define a matrix:
matrix_with_list -->
list([A, B]),
{ phrase(a, A) },
{ phrase(b, B) }.
This looks like we haven't made progress yet:
?- phrase(matrix_with_list, Matrix).
Matrix = [[0, 0, 0, 0, 0], [1, 1, 1, 1, 1]].
But now we can change list//1 a bit to only describe a sublist of its argument list:
optional_list([]) -->
[].
optional_list([_X|Xs]) -->
% skip this X!
optional_list(Xs).
optional_list([X|Xs]) -->
% keep this X
[X],
optional_list(Xs).
This behaves as follows:
?- phrase(optional_list([a, b, c]), Xs).
Xs = [] ;
Xs = [c] ;
Xs = [b] ;
Xs = [b, c] ;
Xs = [a] ;
Xs = [a, c] ;
Xs = [a, b] ;
Xs = [a, b, c].
Now we can adapt the previous definition:
matrix_with_optional_list -->
optional_list([A, B]),
{ phrase(a, A) },
{ phrase(b, B) }.
And we get:
?- phrase(matrix_with_optional_list, Matrix).
Matrix = [] ;
Matrix = [[1, 1, 1, 1, 1]] ;
Matrix = [[0, 0, 0, 0, 0]] ;
Matrix = [[0, 0, 0, 0, 0], [1, 1, 1, 1, 1]].
Pretty good! But it's not great to have all those phrase/2 calls even if they refer to elements that do not end up in the matrix.
So let's generalize some more, to a DCG whose argument is a list of DCGs, and that describes a sublist of the list of lists described by those DCGs:
optional_phrase([]) -->
[].
optional_phrase([_Rule|Rules]) -->
% skip this rule
optional_phrase(Rules).
optional_phrase([Rule|Rules]) -->
% apply this rule
[List],
{ phrase(Rule, List) },
optional_phrase(Rules).
The main insight here was that you can use phrase/2 in a "higher-order" manner, where its first argument is not a literal atom (or functor term) naming a DCG, but a variable bound to such an atom or term. However, you must ensure that these variables are really bound when you apply this rule.
With this the final definition of the matrix is just:
matrix_with_optional_phrase -->
optional_phrase([a, b]).
This now enumerates matrices as before, but it only ever executes phrase/2 for elements that are actually part of the matrix:
?- phrase(matrix_with_optional_phrase, Matrix).
Matrix = [] ;
Matrix = [[1, 1, 1, 1, 1]] ;
Matrix = [[0, 0, 0, 0, 0]] ;
Matrix = [[0, 0, 0, 0, 0], [1, 1, 1, 1, 1]].
DCG notation reserves lists in production to represent sequences of 'tokens'.
Then, your production zeros - for instance - will match a sequence of five zeroes, not a list of five zeroes. There is some confusion here, just because your target language (a sequence of lists) uses the metalanguage notation (Prolog lists indicate sequences of terminals in DCG productions).
I think you could write it simply
zeros --> [ [0,0,0,0,0] ].
ones --> [ [1,1,1,1,1] ].
matrix --> (zeros ; ones), matrix ; [].
test :- phrase(matrix, [ [1,1,1,1,1],[0,0,0,0,0] ]).
Related
I have a written a functional function that tells the user if a list is ordered or not, given the list inputted. However, if a user inputs a variable as the input instead of a list, I would like to output an infinite list. How can I go about this? Here is the current code
ordered([]).
ordered([_]).
ordered([X,Y|Ys]) :- X =< Y , ordered( [Y|Ys] ).
Here is some input
? ordered([1,2,3]).
true
? ordered([1,5,2]).
false
I also want for variables to creat infinite list like so
? ordered(L).
L = [];
L = [_1322] ;
L = [_1322, _1323] ;
L = [_1322, _1323, _1324] ;
L = [_1322, _1323, _1324, _1325].
The list should increase until the user exits as shown.
The list should increase until the user exits as shown.
Solution:
ordered([]).
ordered([_]).
ordered([X,Y|Ys]) :- X #=< Y , ordered( [Y|Ys] ).
EDIT:
SWI Prolog doc
The arithmetic expression X is less than or equal to Y. When reasoning over integers, replace (=<)/2 by #=</2 to obtain more general relations. See declarative integer arithmetic (section A.9.3).
What properties should the list of variables have? The currently accepted answer by Anton Danilov says that [3, 2, 1] is not an ordered list:
?- List = [A, B, C], List = [3, 2, 1], ordered(List).
false.
but it also says that [3, 2, 1] is an instance of an ordered list:
?- List = [A, B, C], ordered(List), List = [3, 2, 1].
List = [3, 2, 1],
A = 3,
B = 2,
C = 1 ;
false.
Viewed logically, this is a contradiction. Viewed procedurally, it is fine, but also the #=< relationship between the variables in the list is meaningless. The comparison of the unbound variables does not say anything about the relationship of the list elements if they are bound to values at some point.
You can use constraints to exclude future unordered bindings:
:- use_module(library(clpfd)).
ordered([]).
ordered([_]).
ordered([X, Y | Xs]) :-
X #=< Y,
ordered([Y | Xs]).
This way you cannot bind the variables in the list to incorrect numbers later on:
?- List = [A, B, C], List = [3, 2, 1], ordered(List).
false.
?- List = [A, B, C], ordered(List), List = [3, 2, 1].
false.
But later correct ordered bindings are still allowed:
?- List = [A, B, C], ordered(List), List = [1, 2, 3].
List = [1, 2, 3],
A = 1,
B = 2,
C = 3 ;
false.
This may not be the best solution, but I believe it can give you some idea of how to do what you need. In SWI-Prolog, the predicate freeze(+Var,:Goal) delays the execution of Goal until Var is bound.
ordered([]).
ordered([_]).
ordered([X,Y|R]) :-
freeze( X,
freeze( Y,
( X #=< Y,
ordered([Y|R]) ) ) ).
Here are some examples with finite lists:
?- ordered([1,2,3]).
true.
?- ordered([1,2,3,0]).
false.
?- ordered(L), L=[1,2,3].
L = [1, 2, 3] ;
false.
?- ordered(L), L=[1,2,3,0].
false.
For an infinite list, you will need to "take" its prefix:
take([]).
take([_|R]) :- take(R).
Here is an example with infinite list:
?- ordered(L), take(L).
L = [] ;
L = [_375396] ;
L = [_376366, _376372],
freeze(_376366, freeze(_376372, (_376366#=<_376372, ordered([])))) ;
L = [_377472, _377478, _377484],
freeze(_377472, freeze(_377478, (_377472#=<_377478, ordered([_377484])))) ;
L = [_378590, _378596, _378602, _378608],
freeze(_378590, freeze(_378596, (_378590#=<_378596, ordered([_378602, _378608])))) ;
L = [_379720, _379726, _379732, _379738, _379744],
freeze(_379720, freeze(_379726, (_379720#=<_379726, ordered([_379732, _379738, _379744]))))
I am quite new in prolog and I've met this structure and I could not figure out how to substact the integer (1) and the matrix.
The exact structure is:
s(1,
[
[[a], [b, c], [f], [s]],
[[4], [k], [1], [5]],
[[f], [s], [w], []],
[[4], [], [w], [3, 53]]
]
)
I've tried with functions that extract elements of lists/matrices, but I haven't met anything in () before.
My guess is you have a variable with the content s(Integer, Matrix) and want to extract the Integer and Matrix. This is actually quite easy:
Lets go with a dummy object S = s(3, [[[1,2],[a,b]]]). You only have S and want to access 3 and [[[1,2],[a,b]]]
?- S = s(3, [[[1,2],[a,b]]]),
S = s(I,M).
I = 3,
M = [[[1, 2], [a, b]]],
S = s(3, [[[1, 2], [a, b]]])
You can put this in some kind of function too. The following example will output an addtion if the predicate name is a, a substraction for s and or h it will put the first parameter as head of a list of the second parameter:
doIt(a(A,B),Out) :-
Out is A+B.
doIt(s(A,B),Out) :-
Out is A-B.
doIt(h(A,B),[A|B]).
?- doIt(a(2,1),A).
A = 3
?- doIt(s(2,1),A).
A = 1
?- doIt(h(2,1),A).
A = [2|1]
I want to make a program in which the user will give a negative number and it will return a list starting from zero till that number. Here is a desired output example
create(-5,L).
L = [0,-1,-2,-3,-4,-5]
could you help me in any way, please?
I would break it up into two auxiliary predicates. The auxiliary predicate is helpful for building the list in the direction you desire.
create(N, L) :-
N < 0,
create_neg(N, 0, L).
create(N, L) :-
N >= 0,
create_pos(N, 0, L).
create_neg(N, N, [N]).
create_neg(N, A, [A|T]) :-
A > N,
A1 is A - 1,
create_neg(N, A1, T).
create_pos(N, N, [N]).
create_pos(N, A, [A|T]) :-
A < N,
A1 is A + 1,
create_pos(N, A1, T).
This will put them in the right order as well:
| ?- create(-5, L).
L = [0,-1,-2,-3,-4,-5] ? a
no
| ?- create(5, L).
L = [0,1,2,3,4,5] ? a
no
| ?-
What you're after is not really a program, just an 'idiomatic' pattern:
?- findall(X, (between(0,5,T), X is -T), L).
L = [0, -1, -2, -3, -4, -5].
Note the parenthesis around the Goal. It's a compound one...
Another way:
?- numlist(-5,0,T), reverse(T,L).
...
Since you provided your code (which as mentioned in comments would be better to appear in your question), one problem I think is that with X>0 and X<0 clauses-cases you will have infinite recursion, maybe it would be better to use abs/1:
create(0,[0]).
create(X,[X|T]):- Y is abs(X), Y > 0,
(X>0 -> N is X-1 ; N is X+1),
create(N,T).
Though still one problem:
?- create(-5,L).
L = [-5, -4, -3, -2, -1, 0] ;
false.
?- create(5,L).
L = [5, 4, 3, 2, 1, 0] ;
false.
The list is built reversed so you could reverse it at the end like:
create_list(N,L):- create(N,L1), reverse(L1, L).
And now:
?- create_list(5,L).
L = [0, 1, 2, 3, 4, 5] ;
false.
?- create_list(-5,L).
L = [0, -1, -2, -3, -4, -5] ;
false.
I need a solution that deletes elements that have pairs of occurrences from list.
I did it in haskell, but i don't have any ideas how to interpretate it in Prolog.
For example [1,2,2,2,4,4,5,6,6,6,6] -> [1,2,2,2,5]
Code in Haskell :
import Data.List
count e list = length $ filter (==e) list
isnotEven = (== 1) . (`mod` 2)
removeUnique :: [Int] -> [Int]
removeUnique list = filter (\x -> isnotEven (count x list) ) list
The following follows your Haskell code.
You need library(reif) for SICStus|SWI.
:- use_module(reif).
oddcount_t(List, E, T) :- % reified: last argument is truth value
tfilter(=(E), List, Eqs),
length(Eqs, Nr),
M is Nr mod 2,
=(M, 1, T).
removeevenocc(List, RList) :-
tfilter(oddcount_t(List), List, RList).
?- removeevenocc([1,2,2,2,4,4,5,6,6,6,6], R).
R = [1,2,2,2,5].
?- removeevenocc([1,X], R).
X = 1, R = []
; R = [1, X],
dif(X, 1).
Note the last question. Here, the list was not entirely given: The second element is left unknown. Therefore, Prolog produces answers for all possible values of X! Either X is 1, then the resulting list is empty, or X is not 1, then the list remains the same.
this snippet uses some of the libraries (aggregate,lists,yall) available, as well as some builtins, like setof/3, and (=:=)/2:
?- L=[1,2,2,2,4,4,5,6,6,6,6],
| setof(K,C^(aggregate(count,member(K,L),C),0=:=C mod 2),Ds),
| foldl([E,X,Y]>>delete(X,E,Y),Ds,L,R).
L = [1, 2, 2, 2, 4, 4, 5, 6, 6|...],
Ds = [4, 6],
R = [1, 2, 2, 2, 5].
edit
to account for setof/3 behaviour (my bug: setof/3 fails if there are no solutions), a possible correction:
?- L=[1],
(setof(K,C^(aggregate(count,member(K,L),C),0=:=C mod 2),Ds);Ds=[]),
foldl([E,X,Y]>>delete(X,E,Y),Ds,L,R).
L = R, R = [1],
Ds = [].
Now there is a choice point left, the correct syntax could be
?- L=[1],
(setof(K,C^(aggregate(count,member(K,L),C),0=:=C mod 2),Ds)->true;Ds=[]),
foldl([E,X,Y]>>delete(X,E,Y),Ds,L,R).
L = R, R = [1],
Ds = [].
I have this list :
C = [[1,0],[2,3],[1,2],[1,3]]
I'll like find if the number 1 included in a sublist inside my list in position [1,_ ] and i like to save to a list Newlist the number of X ..... [1,X].
I will give an example... i have the list C and i am searching for sublist which first element it's 1 and give me the Newlist.
The Newlist must be : Newlist=[0,2,3]
It had the second element of the sublists who has the number 1 at the first element.
If you use SWI-Prolog with module lambda.pl, (you can find it at http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl) you can write
:- use_module(library(lambda)).
my_filter(V, L, R) :-
foldl(V+\X^Y^Z^(X = [V,W]
-> append(Y, [W], Z)
; Z = Y),
L, [], R).
nth0/3 allows to access list' elements by index:
?- C = [[1,0],[2,3],[1,2],[1,3]], findall(P, nth0(P, C, [1,_]), NewList).
C = [[1, 0], [2, 3], [1, 2], [1, 3]],
NewList = [0, 2, 3].
edit I'm sorry I didn't read the question right. nth0 is misleading. Could be instead
findall(E, member([1,E], C), NewList)
You need a "filter". This is what it could look like:
filter_1_at_pos_1([], []). % The new list is empty when the input list is empty
filter_1_at_pos_1([[1,X]|Sublist], [X|Xs]) :- % The first element is 1 so the
% second element belongs to the
% new list
!, filter_1_at_pos_1(Sublist, Xs). % filter the remainder of the list
filter_1_at_pos_1([[N,_]|Sublist], Xs) :-
N \== 1, % The first element is not 1, ignore the second element
!, filter_1_at_pos_1(Sublist, Xs).
As #mbratch suggested, just define the solution for one element of the input list for each possible condition, in this case 1) empty list 2) first element is 1 and 3) first element is not 1.
?- C = [[1,0],[2,3],[1,2],[1,3]], filter_1_at_pos_1(C, NewList).
C = [[1, 0], [2, 3], [1, 2], [1, 3]],
NewList = [0, 2, 3].
The cuts make the predicate deterministic. The cut in the last clause is not necessary.