I am trying to copy a list so that the original list is not changed by whatever operations I perform on the new list. I have looked at prolog, copying lists and Prolog - copy a piece of list. However, neither of these options generates a list that is "independent" from its "parent".
Coming from an imperative background, some Prolog concepts are hard to grasp and I'm sure I'm missing something here. So my question is is it possible to create a deep copy of a list in Prolog?
Thank you in advance.
A list is just a term dressed in fancy clothing.
[] is a simple atom.
[a] is syntactic sugar for the term .(a,[])
[a,b] is syntactic sugar for the term .(a,.(b,[])).
[H|T] is syntactic sugar for the term .(H,T)
That's all there is to it. Conserves parentheses and periods, it does.
So what you're talking about really has nought to do with lists, but everything to do with terms. If the term in question is fully bound -- meaning it and, recursively, any sub-terms, do not contain any non-unified variables, the term is immutable. But if it contains any unbound variables, it's mutable.
So, what you're talking about is doing a recursive tree walk to clone a term, replacing any unbound variables with a fresh copy. The trick is that you need to map each variable encountered with its replacement. so something like [A,A,B,B,foo(A,B,C),C] comes out as [X,X,Y,Y,foo(X,Y,Z),Z] and not [V1,V2,V3,V4,foo(V5,V6,V7),V8].
Luckily, Prolog comes with build-in tooling for that: copy_term/2.
But I imagine your instructor is not looking for you to be using that.
Traversing an arbitrary term is not difficult. Something along these lines (don't have a Prolog convenient to hand at the moment):
clone_deep( T , C ) :- clone_deep( T, [], C, _ ).
% T: source term
% S: symbol table
% C: cloned term
% S1: [possibly] extended symbol table
clone_deep( T , S , C, S1 ) :-
var(T), % term is a variable
map_var(T,S,C,S1) % fetch/add its mapping to the symbol table.
.
clone_deep( T , S , T , S ) :-
atomic(T) % term is atomic (number, atom, etc.)
.
clone_deep( T , S , C, S1 ) :-
compound(T), % term is a compound term like foo() or foo(X,Y).
T =.. [Functor|Args], % decompose it into its functor and its argument list
clone_deep(Args,S,Args1,S1), % recursively clone its arguments
C =.. [Functor|Args1] % recompose the new compound term
.
% recursively run down the list of symbol mappings to find the self-same variable
% add it if not found.
map_var( V , [ X:C | S ] , C , [ X:C | S ] ) :- X == V, !. % V is the same ref as X -- already in symbol table
map_var( V , [ X:Y | S ] , C , [ X:Y | Z ] ) :- X \== V, !, % V and X are different refs
fresh_symbol(V,S,C,Z). %
map_var( V , [] , C , [ X:C ] ). % not yet mapped var.
Related
/* Define a Prolog predicate replicate/3 which corresponds to
* the Haskell function of the same name, except that the numeric
* argument is expressed symbolically.
*
* For example, replicate(s(s(s(0))),a,[a,a,a]) should be satisfied.
*/
So far I've come to this solution:
replicate(0,_,[]).
replicate(X,Y,[Y|Z]) :- replicate(p(X),Y,Z).
but the problem is that the s(s(s(0))) is not getting reduced by the pred function. it results into p(p(p(s(s(s(0))))))
could you guys help me out?
This is Haskell's replicate coded with the (deprecated) n+k patterns:
replicate 0 _ = []
replicate (n+1) a = a : x where x = replicate n a
This directly corresponds to the Prolog definition:
replicate(0, _, []).
replicate(s(N), A, [A | X]) :- replicate(N, A, X).
We just move the result into the arguments list, and make it the last argument to the predicate:
x = replicate n a -----> replicate(N, A, X).
The pattern matching is the same. What's not the same, is that Prolog is not an expression-oriented language. There are no expressions which get evaluated before being used as arguments in the next function call; instead, there are terms which are auto-quoted, always, used as is as arguments to predicates.
The predicate if_/3 seems to be fairly popular among the few main contributors in the Prolog part of Stack Overflow.
This predicate is implemented as such, courtesy of #false:
if_(If_1, Then_0, Else_0) :-
call(If_1, T),
( T == true -> call(Then_0)
; T == false -> call(Else_0)
; nonvar(T) -> throw(error(type_error(boolean,T),_))
; /* var(T) */ throw(error(instantiation_error,_))
).
However, I have been unable to find a clear, simple, and concise explanation of what this predicate does, and what use it has compared to e.g. the classical if-then-else construct of Prolog if -> then ; else.
Most links I have found directly use this predicate and provide little explanation as to why it gets used, that a non-expert in Prolog could understand easily.
In old-fashioned Prolog code, the following pattern arises rather frequently:
predicate([], ...).
predicate([L|Ls], ...) :-
condition(L),
then(Ls, ...).
predicate([L|Ls], ...) :-
\+ condition(L),
else(Ls, ...).
I am using lists here as an example where this occurs (see for example include/3, exclude/3 etc.), although the pattern of course also occurs elsewhere.
The tragic is the following:
For an instantiated list, pattern matching can distinguish the first clause from the remaining two, but it cannot distinguish the second one from the last one because they both have '.'(_, _) as the primary functor and arity of their first argument.
The conditions in which the last two clauses apply are obviously mutually exclusive.
Thus, when everything is known, we want to obtain an efficient, deterministic predicate that does not leave choice points, and ideally does not even create choice points.
However, as long as not everything can be safely determined, we want to benefit from backtracking to see all solutions, so we cannot afford to commit to either of the clauses.
In summary, the existing constructs and language features all fall short in some way to express a pattern that often occurs in practice. Therefore, for decades, it seemed necessary to compromise. And you can make a pretty good guess in which direction the "compromises" usually go in the Prolog community: Almost invariably, correctness is sacrificed for efficiency in case of doubt. After all, who cares about correct results as long as your programs are fast, right? Therefore, until the invention of if_/3, this was frequently wrongly written as:
predicate([], ...).
predicate([L|Ls], ...) :-
( condition(L) ->
then(Ls, ...).
; else(Ls, ...).
)
The mistake in this is of course that when the elements are not sufficiently instantiated, then this may incorrectly commit to one branch even though both alternatives are logically possible. For this reason, using if-then-else is almost always declaratively wrong, and stands massively in the way of declarative debugging approaches due to its violation of the most elementary properties we expect from pure Prolog programs.
Using if_/3, you can write this as:
predicate([], ...).
predicate([L|Ls], ...) :-
if_(condition(L),
then(Ls, ...),
else(Ls, ...)).
and retain all desirable aspects. This is:
deterministic if everything can be safely decided
efficient in that it does not even create choice points
complete in that you never incorrectly commit to one particular branch.
The price of this is rather affordable: As Boris mentioned in the comments, you need to implement a reification. I have now some experience with this and found it rather easy with some practice.
Good news everyone: In many cases, condition is of the form (=)/2, or (#=)/2, and the first even ships with library(reif) for free.
For more information, see Indexing dif/2 by Ulrich Neumerkel and Stefan Kral!
Let's try to solve a simple problem using if_/3; for example, I will try to partition a list (sorted on a predicate p/2) in two lists: a prefix in which, for every element X, we have p(X, true), and a rest (in which, if the list was sorted on p/2, we would have p(X, false).
I will use the library reif as here. So, here is the complete code of my program:
:- use_module(reif).
pred_prefix(Pred_1, List, L_true, L_false) :-
pred_prefix_aux(List, Pred_1, L_true, L_false).
pred_prefix_aux([], _, [], []).
pred_prefix_aux([X|Xs], Pred_1, True, False) :-
if_( call(Pred_1, X),
( True = [X|True0],
pred_prefix_aux(Xs, Pred_1, True0, False)
),
( True = [],
False = [X|Xs]
)
).
The predicate passed to this meta-predicate will take two arguments: the first is the current list element, and the second will be either true or false. Ideally, this predicate will always succeed and not leave behind choice points.
In the first argument of if_/2, the predicate is evaluated with the current list element; the second argument is what happens when true; the third argument is what happens when false.
With this, I can split a list in leading as and a rest:
?- pred_prefix([X, B]>>(=(a, X, B)), [a,a,b], T, F).
T = [a, a],
F = [b].
?- pred_prefix([X, B]>>(=(a, X, B)), [b,c,d], T, F).
T = [],
F = [b, c, d].
?- pred_prefix([X, B]>>(=(a, X, B)), [b,a], T, F).
T = [],
F = [b, a].
?- pred_prefix([X, B]>>(=(a, X, B)), List, T, F).
List = T, T = F, F = [] ;
List = T, T = [a],
F = [] ;
List = T, T = [a, a],
F = [] ;
List = T, T = [a, a, a],
F = [] .
How can you get rid of leading 0's for example:
?- pred_prefix([X, B]>>(=(0, X, B)), [0,0,1,2,0,3], _, F).
F = [1, 2, 0, 3].
Of course, this could have been written much simpler:
drop_leading_zeros([], []).
drop_leading_zeros([X|Xs], Rest) :-
if_(=(0, X), drop_leading_zeros(Xs, Rest), [X|Xs] = Rest).
Here I have just removed all unnecessary arguments.
If you would have to do this without if_/3, you would have had to write:
drop_leading_zeros_a([], []).
drop_leading_zeros_a([X|Xs], Rest) :-
=(0, X, T),
( T == true -> drop_leading_zeros_a(Xs, Rest)
; T == false -> [X|Xs] = Rest
).
Here, we assume that =/3 will indeed always succeed without choice points and the T will always be either true or false.
And, if we didn't have =/3 either, you'd write:
drop_leading_zeros_full([], []).
drop_leading_zeros_full([X|Xs], Rest) :-
( X == 0 -> T = true
; X \= 0 -> T = false
; T = true, X = 0
; T = false, dif(0, X)
),
( T == true -> drop_leading_zeros_full(Xs, Rest)
; T == false -> [X|Xs] = Rest
).
which is not ideal. But now at least you can see for yourself, in one single place, what is actually going on.
PS: Please read the code and the top level interaction carefully.
I have a function called member that is supposed to take as arguments:
1) a name
2) a list of names.
The list of names is already defined in my program, so I want to be able to call the method with a name and the list that's already initialized in the program.
For example, my Prolog program contains...
namesList(mike,joe,bob,jill).
member(Element, [Element|_]):-!.
member(Element, [_|Tail]):-member(Element,Tail).
So, when I'm at a Prolog prompt and type in member(mike,namesList). Prolog should output true, but instead prints false.
Am I calling the function correctly, or can I not use an already instantiated list?
First, Prolog doesn't have functions: it has predicates.
Second, A non-empty prolog list is written using square brackets — [a,b,c,d] with the empty list denoted by the atom []. Lists are actually represented by the structure ./2, where the first argument is the first item (the head) of the list and the second argument is the remainder of the list, either another non-empty list, or the empty list itself. It's what the compiler writers like to call syntactic sugar. So
[a] is exactly equivalent to .(a,[]).
[a,b] is exactly equivalent to .(a,.(b,[])).
[a,b,c] is exactly equivalent to .(a,.(b,.(c,[])))
etc.
And
[A|B] is exactly equivelent to .(A,B).
You can see why the square brackets notation is a little easier to use.
So...you could store your names list this:
names_list( [mike,joe,bob,jill] ).
in which case, you could say:
?- names_list( Names ) , member(mike,Names) .
true.
However...You might find it easier if you maintained your names in a more...prolog-like manner:
name( mike ) .
name( joe ) .
name( bob ) .
name( jill ) .
Then...
You can check for existence in the usual way:
?- N = sam , name(N) ,
false.
Or, you can iterate over them via backtracking:
?- name(N).
N = mike ;
N = joe ;
N = tim ;
N = jill.
And, if you really need them as a list, it's easy to get them in that form:
?- findall(N,name(N),Ns).
Ns = [mike, joe, tim, jill].
Finally, one should note the list of names could be extracted from your
names_list( mike , joe , bob , jill ).
but it's not exactly the most elegant thing in the world:
extract( Name , Arguments ) :-
atom(Name) ,
current_functor(Name,Arity) ,
length(Arguments,Arity) ,
Goal =.. [Name|Arguments] ,
callable(Goal) ,
call(Goal)
.
Once you have that, you can say:
?- extract(names_list,Names) , member(mike,Name).
true.
I have a little problem with my homework to school. I have to write code, which will find any x (int or letter) in a list of lists.
I have something like this:
find x xxs = [ [ x | x <- xs, x `elem` xs ] | xs <- xxs ]
Hugs98 accept it without any exception, but it doesn't work.
Input: find 2 [[1,1,1,1],[4,4,4,4],[3,3,3]]
Output: [[1,1,1,1],[4,4,4,4],[3,3,3,3]]
With a little renaming, I think you just wrote this:
find x yss = [ [ y | y <- ys, y `elem` ys ] | ys <- yss ]
I don't think that's what you meant to do. (In your code, you've got two variables named x, one shadowing the other.)
Your question doesn't state what tools you are or aren't allowed to use.
Clearly elem finds stuff in a list. And by "finds", I mean it returns a Bool indicating whether the target item is present or not. But how to handle a list of lists?
A list comprehension always returns a list, so if you were hoping for find to return a Bool, you don't want a list comprehension.
You can use map to apply elem to every list in the list of lists - but now you have a list of Bools. There are two ways to deal with that. One slightly kludgy way is to use elem to see if the list contains True anywhere. But a more sane way is to use the built-in or function, which takes the logical-OR of a list of Bools. (There is also a corresponding and function.)
find x yss = or (map (x `elem`) yss)
There's another way you can do this too; there's a built-in function called any, which applies a function to a list of stuff and returns True if the supplied function ever returns True. So you can do
find x yss = any (x `elem`) yss
I have an input of a list of pairs:
[[abs_(p,X,Y,Z),abs_(f,X,Y,Z)],[abs_(p,X,Y,Z),abs_(l,Z,P)]]
I want check if a pair have the same number of arguments, in this case yes:
[abs_(p,X,Y,Z),abs_(f,X,Y,Z)]
In the second case the answer is no.
This is just an example because more generally, I want to know which pair have the same number of arguments. The output for the input should be:
[[abs_(p,X,Y,Z),abs_(f,X,Y,Z)]
What do I have to do?
run( [], Tail) :- Tail=[].
run( [ [First,Second] | Tail ], Output ) :- First =.. List1, Second =.. List2,
length(List1,N1), length(List2, N2), N2 is N1, !, run(Tail, Tail2),
append( [ [First | [Second]] ], Tail2, Output ).
run( [H|T], Output ) :- run(T, Output).
First rule is base case. Second rule checks the number of arguments in first pair if its same run the recursive call and append the output from recursive call with and this pair to Output. Because of cut if N2 equals N1 it doesn't call third rule. And third rule discard the unmatched pair and call itself with tail of the list. Hope it helps.
Prolog provides a strange infix operator =.. called "univ" which converts between compound terms and a list that begins with the functor followed by the arguments to that functor.
Hence a Prolog query something like this:
?- abs_(p,X,Y,Z) =.. L.
L = [abs_,p,X,Y,Z]
yes
So I would use length/2 on the lists produced by the "univ" operator to check that two compound terms have an equal number of arguments.
You can also use pattern matching to break each pair into terms, and use the functor predicate to check the arity of those terms.