Prolog: Difference of two lists - list

Pretty new to Prolog. I'm trying to give two lists and have the difference of the two returned to me. The second list can have bound variables and unbound variables in it. I've tried tracing this and it recurses all the way through and gives me a correct list in NewL, but then on the way back it negates all the deletes I've made. What is going wrong ? Thanks for the help!
% Find difference between two lists, return result in Difference
difference(List,[H|T],Difference) :- % When H is unbound var, use Tail
var(H),!,difference(List,T,Difference),!.
difference(List,[H|T],Difference) :- % When H is bound var, remove from List.
subtract(List,[H],NewL),
difference(NewL,T,Difference),!.

Assuming that subtract/3 comes from SWI-Prolog library, and thus is correct, you are left with just one possibility: you forgot to declare the base case on the second argument, that drives the recursion.
And take in account the comment from #mog, cuts should be used just when required. Of course, to decide when are required can be difficult...

Related

How can I calculate the length of a list containing lists in OCAML

i am a beginner in ocaml and I am stuck in my project.
I would like to count the number of elements of a list contained in a list.
Then test if the list contains odd or even lists.
let listoflists = [[1;2] ; [3;4;5;6] ; [7;8;9]]
output
l1 = even
l2 = even
l3 = odd
The problem is that :
List.tl listoflists
Gives the length of the rest of the list
so 2
-> how can I calculate the length of the lists one by one ?
-> Or how could I get the lists and put them one by one in a variable ?
for the odd/even function, I have already done it !
Tell me if I'm not clear
and thank you for your help .
Unfortunately it's not really possible to help you very much because your question is unclear. Since this is obviously a homework problem I'll just make a few comments.
Since you talk about putting values in variables you seem to have some programming experience. But you should know that OCaml code tends to work with immutable variables and values, which means you have to look at things differently. You can have variables, but they will usually be represented as function parameters (which indeed take different values at different times).
If you have no experience at all with OCaml it is probably worth working through a tutorial. The OCaml.org website recommends the first 6 chapters of the OCaml manual here. In the long run this will probably get you up to speed faster than asking questions here.
You ask how to do a calculation on each list in a list of lists. But you don't say what the answer is supposed to look like. If you want separate answers, one for each sublist, the function to use is List.map. If instead you want one cumulative answer calculated from all the sublists, you want a fold function (like List.fold_left).
You say that List.tl calculates the length of a list, or at least that's what you seem to be saying. But of course that's not the case, List.tl returns all but the first element of a list. The length of a list is calculated by List.length.
If you give a clearer definition of your problem and particularly the desired output you will get better help here.
Use List.iter f xs to apply function f to each element of the list xs.
Use List.length to compute the length of each list.
Even numbers are integrally divisible by two, so if you divide an even number by two the remainder will be zero. Use the mod operator to get the remainder of the division. Alternatively, you can rely on the fact that in the binary representation the odd numbers always end with 1 so you can use land (logical and) to test the least significant bit.
If you need to refer to the position of the list element, use List.iteri f xs. The List.iteri function will apply f to two arguments, the first will be the position of the element (starting from 0) and the second will be the element itself.

Assign variable in list

I've got a problem with Prolog lists.
Let's say I've got this predicate:
array(p, [A,B,C]).
When I do:
array(p,X).
I got: X = [_,_,_]
Now, considering I've got this predicate:
p1(1) :- array(p1, [1,B1,C1]).
I expected to get:
X = [1,_,_]
but instead, the result is the same as before. Is such a thing even possible in Prolog? Another question is if somehow we can set these values, could we overwrite these values in the same way? I understand that in the prolog variables are assigned only once but I would like to somehow get a dynamic list.
I'm not sure what you mean by "paradigm," and I'm very unclear on what you're trying to do with this code. If you have this at the toplevel:
array(p, [A,B,C]).
you are defining a fact array/2, which associates p with a list of three uninstantiated variables. Your first query amounts to retrieving this fact.
Your second "paradigm" is really the definition of a rule or predicate p1/1, which takes a single argument, which must be 1 for the rule to fire. The body of this second predicate is a call to the predicate array/2 which is definitely going to fail. I don't see how you could possibly get the same result as before, because you defined array(p, ...) before and now you are looking for array(p1, ...). Furthermore, there is no X in your second query, so there is no reason for X to appear in the result, and it definitely would not, even if you had called array(p, ...) instead of array(p1, ...).
I think what you're trying to do here is probably set up some kind of set of three variables and then unify each of them in turn as you proceed along some calculation. To do something like that is possible and easy in Prolog, but the fact database is not going to participate in this process really. You're going to have to write predicates that pass your variables along to other predicates that will unify them and return them bound. None of this is very hard, but it looks like you're going to have to go back and understand the fundamentals here a little better. You're far enough off track here that I don't think anyone can really answer your question as stated, because there's too much confusion in it.

How to declare a list in Prolog?

I have browsed through various answers on SO about how to declare a list but I keep getting error messages. I am reading the section on lists from a book that I have but there still isn't an example on how to correctly declare them.
I am doing a project for my class. I have a random set of questions but when the user answers one then that question cannot be repeated (questions are to be random).
I have this part done but I wanted to create a list so that when a question is asked, I want to add that question number to my list. I have tried various ways and I still can't do it!
test(N):- list(P), member(N, P).
list = [].
start :-
write('Answer the questions correctly'), nl,
X is 0,
push(X,list,[X|list]),
test(X).
This snippet is just to make the list code. As I understand it I want to push X, in this case 0, to the head of the list. Since my list was declared as empty I figure it would work. I am getting this error:
No permission to modify static procedure `(=)/2'
I have tried to understand what this means but because everyone's code is different there are many different answers and I am overwhelmed. This is my first time programming in Prolog.
No permission to modify static procedure `(=)/2'
In Prolog you do not construct list by declaring them as you tried to do with
list = [].
Prolog values start with lower case letters and variables start with upper case letters. That is not common among programming languages but makes it easy to create new variables, you don't have to declare them, just use an upper case letter where you need a variable.
Prolog does not use assignment or have methods. Prolog uses syntactic unification and has predicates. So when you see [] as a argument being passed, that is when the list is either constructed, or unified with a variable.
You probably want something like this
begin :-
% In the next statement I am doing what you would consider
% constructing a list.
ask([]).
ask(List) :-
write('Answer the questions correctly'), nl,
get_answer(A),
% Here the answer in A is added to the head of the list using
% the list operator that combines a head with a tail, `|`.
% This is how your idea of a push is done with a list.
test([A|List]).
% When this is called from
% get_answer(A), A will be unified with 0.
get_answer(0).
% The next predicate `test` with two clauses does what your were trying to do with
% `member(N,P)`. It uses recursion which needs one clause to recursively process
% a list and one clause, the base case, to handle an empty list.
% When the list is empty, do nothing.
test([]).
test([H|T]) :-
% H is the head of the list
% do something with head of list by adding more code here.
% T is the tail of the list.
% Recursively call test with the tail of the list
% to process the remainder of the list.
test(T).

Prolog, find value with smallest difference to reference value in a list

I need your help with Prolog, I hope my explanation is not too difficult.
The general problem is: i have a list with several feature structures (which are actually feature:value lists in Prolog) with a value "time:xyz" among other values. I have a reference feature structure with a reference time. Now I need the feature structure with the closest time value to my reference time.
My plan is to go through the the list and compare each entry with the current smallest difference to the reference time.
The problem is that the variable MinFSR which is the current minimum has no value the first time minimum(...) is called. So I get an error.
How can I check whether MinFSRhas already a value? I want to check this and if it hasn't a value then I want to call list_min with the H as new MinFSR.
list_min([], ReferenceFSR, MinFSR). %if list is empty stop
list_min([H|T], ReferenceFSR, MinFSR) :-
minimum(H, MinFSR, ReferenceFSR, Min1),
list_min(T, ReferenceFSR, Min1).
minimum(FSR1, FSR2, ReferenceFSR, MinFSR):-
% reads out and compares the time of FSR1 and FSR2 to the referenceFSR
% and MinFSR is the FSR1 or FSR2 depending on which has the smaller
% difference
I hope you can understand my problem although I wrote it very complicated.
Thanks in advance!
I think you're close, but your predicate needs to be reworked a little. The recursive case should look at the two head elements of the list since you are already given a predicate, minimum/4, which yields the desired choice from comparing a pair of values.
list_min([X], _, X). % X is min for single list, [X]
list_min([X,Y|T], ReferenceFSR, MinFSR) :-
minimum(X, Y, ReferenceFSR, Min),
list_min([Min|T], ReferenceFSR, MinFSR).

Silly detail enquiry about Prolog unification

In Prolog:
?-P=[A|B], P=[1,_].
P = [1, _G1091],
A = 1,
B = [_G1091]
B is shown as [_G1091] showing it's an uninstantiated variable. However, if I change a tiny bit...
?-P=[A|B], P=[1|_].
P = [1,B],
A = 1,
All of a sudden it's not interested in showing me that B is uninstantiated but still a variable ready to unify with anything.. how come? (I like to focus on weird details sometimes :) )
The precise details of Prolog syntax are sometimes quite subtle. To get used to it use write_canonical/1 which shows you the term in functional notation:
?- write_canonical([A|B]).
'.'(_1,_2)
true.
?- write_canonical([1,_]).
'.'(1,'.'(_1,[]))
true.
May I recommend a "drill"-exercise to get used to Prolog's list notation:
Take some list like [[1,2],3] and now try to write it down in as many variants you can imagine.
?- [[1,2],3] == [[1,2],3|[]].
true.
etc.
In many Prologs the toplevel lets you take the last input (often: cursor-up) such that you can re-edit the right-hand side rapidly.
In the first case:
?-P=[A|B], P=[1,_].
you are stating that P is a list with two elements, the first one being the number 1 (unified to variable A). Therefore, B has to be a list with one element (an unnamed variable).
On the other hand, in the second case:
?-P=[A|B], P=[1|_].
you are stating that P is a list with at least one element (1 again unified to A) but you are not stating anything else. B can be either an empty list, or a list with any amount of elements.
If you look at the second part of each query, the first amounts to
P=.(1,.(_,[]))
while the second amounts to
P=.(1,_)
In the first, B is bound to .(_,[]); that is, a list that contains an uninstantiated variable
In the second, B is bound to an uninstantiated variable
When a variable is just bound to an uninstantiated variable, there's no point in showing it; in the first example it's bound to something with some additional structure, so there is a point in showing it.