Using list name as nth0 argument in prolog - list

I want to use list name as nth0 function argument, which should give me nth element,
for example:
nth0(2,[1,2,3],X).
X = 3.
defined list:
L = [1,2,3].
nth0(2,L,X).
I want it to return X = 3. it returns random numbers in L, ̀L = [_10614, _10620, X|_10628].

I'm guessing you are somehow running these two instructions at different times.
If you run them as a joint expression:
L = [1,2,3], nth0(2,L,X).
You should get the right answer.

Related

Prolog: compare list elements and sum

New to prolog and trying to implement the following function that takes 3 lists:
True if lists are the same length
True if elements of third list is sum of the two lists
Example: fn([1,2,3],[4,5,6],[5,7,9]) returns true. Note that the sum is element-wise addition.
This is what I have so far:
fn([],[],[]).
fn([_|T1], [_|T2], [_|T3]) :-
fn(T1,T2,T3), % check they are same length
fn(T1,T2,N1), % check that T3=T1+T2
N1 is T1+T2,
N1 = T3.
From what I understand, the error is due to the base case (it has empty lists which causes error with evaluation of addition?)
Thanks for any help and explanations!
In addition to #GuyCoder's answer, I would point out that it is worthwhile to consider using one of the maplist predicates from library(apply) when modifying all elements of lists. You can use a predicate to describe the relation between three numbers...
:- use_module(library(apply)). % for maplist/4
num_num_sum(X,Y,S) :-
S is X+Y.
... and subsequently use maplist/4 to apply it to entire lists:
fn(X,Y,Z) :-
maplist(num_num_sum,X,Y,Z).
This predicate yields the desired results if the first two lists are fully instantiated:
?- fn([1,2,3],[4,5,6],X).
X = [5,7,9]
However, due to the use of is/2 you get instantiation errors if the first two lists contain variables:
?- fn([1,A,3],[4,5,6],[5,7,9]).
ERROR at clause 1 of user:num_num_sum/3 !!
INSTANTIATION ERROR- X is _+B: expected bound value
?- fn([1,2,3],[4,5,A],[5,7,9]).
ERROR at clause 1 of user:num_num_sum/3 !!
INSTANTIATION ERROR- X is A+B: expected bound value
If you only want to use the predicate for lists of integers, you can use CLP(FD) to make it more versatile:
:- use_module(library(apply)).
:- use_module(library(clpfd)). % <- use CLP(FD)
int_int_sum(X,Y,S) :-
S #= X+Y. % use CLP(FD) constraint #=/2 instead of is/2
fnCLP(X,Y,Z) :-
maplist(int_int_sum,X,Y,Z).
With this definition the previously problematic queries work as well:
?- fnCLP([1,A,3],[4,5,6],[5,7,9]).
A = 2
?- fnCLP([1,2,3],[4,5,A],[5,7,9]).
A = 6
Even the most general query yields results with this version:
?- fnCLP(X,Y,Z).
X = Y = Z = [] ? ;
X = [_A],
Y = [_B],
Z = [_C],
_A+_B#=_C ? ;
X = [_A,_B],
Y = [_C,_D],
Z = [_E,_F],
_A+_C#=_E,
_B+_D#=_F ? ;
.
.
.
Since the numbers in the above answers are not uniquely determined, you get residual goals instead of actual numbers. In order to get actual numbers in the answers, you have to restrict the range of two of the lists and label them subsequently (see documentation for details), e.g. to generate lists containing the numbers 3,4,5 in the first list and 6,7,8 in the second list, you can query:
label the lists
restrict the domain | |
v v v v
?- fnCLP(X,Y,Z), X ins 3..5, Y ins 6..8, label(X), label(Y).
X = Y = Z = [] ? ;
X = [3],
Y = [6],
Z = [9] ? ;
X = [3],
Y = [7],
Z = [10] ? ;
.
.
.
X = [3,4],
Y = [6,7],
Z = [9,11] ? ;
X = [3,4],
Y = [6,8],
Z = [9,12] ? ;
.
.
.
On an additional note: there are also clp libraries for booleans (CLP(B)), rationals and reals (CLP(Q,R)) that you might find interesting.
From what I understand, the error is due to the base case.
I don't see it that way.
The first problem I see is that you are trying to process list which leads to thinking about using DCGs, but since you are new I will avoid that route.
When processing list you typically process the head of the list then pass the tail back to the predicate using recursion.
e.g. for length of list you would have
ln([],N,N).
ln([_|T],N0,N) :-
N1 is N0+1,
ln(T,N1,N).
ln(L,N) :-
ln(L,0,N).
The predicate ln/2 is used to set up the initial count of 0 and the predicate ln/3 does the work using recursion. Notice how the head of the list is taken off the front of the list and the tail of the list is passed recursively onto the predicate again. When the list is empty the predicate ln([],N,N). unifies, in this case think copies, the intermediate count from the second position into the third position, which it what is passed back with ln/2.
Now back to your problem.
The base case is fine
fn([],[],[]).
There are three list and for each one look at the list as [H|T]
fn([H1|T1],[H2|T2],[H3|T3])
and the call to do the recursion on the tail is
fn(T1,T2,T3)
all that is left is to process the heads which is
H3 is H1 + H2
putting it all together gives us
fn([],[],[]).
fn([H1|T1], [H2|T2], [H3|T3]) :-
H3 is H1 + H2,
fn(T1,T2,T3).
and a quick few checks.
?- fn([],[],[]).
true.
?- fn([1],[1],[2]).
true.
?- fn([1,2],[3,4],[4,6]).
true.
?- fn([1,2],[3,4,5],[4,6,5]).
false.
With regards to the two conditions. When I look at exercises problems for logic programming they sometimes give a condition like True if lists are the same length or some other condition that returns true. I tend to ignore those at first and concentrate on getting the other part done first, in this case elements of third list is sum of the two lists then I check to see if the other conditions are correct. For most simple classroom exercises they are. I sometimes think teacher try to give out these extra conditions to confuse the student, but in reality the are there just to clarify how the code should work.

Take out first elements from nested lists in Prolog

Problem: I need to transform this list: [[1,2],[3,4],[5,6]] to [1,3,5], by taking only first items from each sub-list in first list and creating new list with all of them. Language is SWI-Prolog.
My solution: To do this, I wrote this code:
getFirstItems([], Result).
getFirstItems([H|T], Result) :-
[H2|T2] = H,
append(Result,H2,Result2),
getFirstItems(T, Result2).
Issue: But this fails to infinite recursion when tail always equals to [[5,6]]
Question: how to solve this issue and solve this problem correctly?
You are complicating things too much. You need to reason with a declarative mindset, and thus implement what the relationships between the list of lists and the list of first elements are.
Here is a solution:
first_items([], []).
first_items([[H|_]|T], [H|T2]) :-
first_items(T, T2).
Indeed, the only two things we need to state to describe that relationship are:
If the list of lists is empty, then so is the list of first elements.
a first element H is in the list of first elements, followed by the first elements (T2) of the rest of the list of lists (T).
Example queries:
?- first_items([[1,2],[3,4],[5,6]], Z).
Z = [1, 3, 5].
?- first_items(L, [1,3,4]).
L = [[1|_22058], [3|_22070], [4|_22082]].
?- first_items(L, Z).
L = Z, Z = [] ;
L = [[_22048|_22050]],
Z = [_22048] ;
L = [[_22048|_22050], [_22066|_22068]],
Z = [_22048, _22066]
…

Replace a certain value in OCaml list in every occurrence with another value

I'm working out a simple program that replaces a certain value (in every occurrence) with another given value inside a list. I tried to follow this:
Ocaml, replace all specified elements with a given element in a list
But unfortunately I can't use the when construct here. Here's my code:
let rec replace (l:int list) (i:int) (j:int) :int list =
match l with
| hd::tl -> if hd = i then j::tl else replace tl i j
| [] -> l
;;
When I tried to replace an entry, It doesn't gives the whole list. instead it only gives the changed value. Can anyone help me out ?
Your description of the problem doesn't match your code, or maybe I don't understand. If I try your code here's what I see:
# replace [1; 4; 1; 4; 2] 4 6 ;;
- : int list = [6; 1; 4; 2]
I see two problems. First, the return value starts at the first replaced value rather than the beginning of the list. Second, only one value is replaced, not all values.
To solve the first problem, you have to make sure you return the full list all the time. You're not returning the full list when hd = i is false.
To solve the second problem you need to process the tail of the list in all cases. You're not processing the tail of the list when hd = i is true.

Writing multiple functions in SML - Sequential Composition

I would like to understand how sequential composition works much better than I do now in SML. I have to write a program that takes a list of integers and moves the integer at index zero to the last index in the list. ie. [4, 5, 6] -> [5, 6, 4].
The code I have right now is:
- fun cycle3 x =
= if length(x) = 1 then x
= else (List.drop(x, 1);
= x # [hd(x)]);
val cycle3 = fn : 'a list -> 'a list
The question lies in my else statement, what I want to happen is first concatenate the first term to the end, and then second drop the first term. It seems simple enough, I just don't understand how to perform multiple functions in a particular order using SML. My understanding was that the first function called has the scope of the second function that would have the scope of the third function.. etc etc.. What am I doing wrong here?
Most things in SML are immutable -- your function, rather than modifying the list, is building a new list. List.drop(x,1) evaluates to a new list consisting of all but the first element of x, but does not modify x.
To use your method, you would bind the result of List.drop(x,1) to a variable, as in the following:
fun cycle3 x = if length x = 1
then x
else let
val y = List.drop(x,1)
in
y # [hd(x)]
end
Alternately, a cleaner way of doing this same thing, that also handles the possibility of an empty list:
fun cycle3 [] = []
| cycle3 (x::xs) = xs # [x]

Updating List Elements, Haskell

I have homework where I am to update a list using a function that takes two elements and returns a value of part of the first element given in the function. So it's required to update the entire listing by going through each element and update its value by applying the function against all other elements in the list (including itself).
So far I've been trying to firstly map the list (so that each element is done the same) and then specifically update each elements value by mapping again just the value of the specified element however in trying to map just the specific value through: the function, the specific element and the entire list I keep getting complaints that I'm inferring the list of values made from the 'map function p#list list' rather than simply giving the value at p#list.
Here is a sample of what I've been trying to implement:
res :: X -> X -> Z -- function given
myf :: [X] -> [X] -- Here is my function
myf ps = map newf ps
where
newf p#(X oldz) = X newz
newz = map (res p) ps
Is this the correct method to try to update a list against the entire list itself?
EDIT: spelling mistakes and grammar- my apologies on not also putting the homework tag on it
Is this the correct method to try to update a list against the entire list itself?
I'm not sure that code is correct for any task.
Looks like you assumes that p#(X oldz) is taking element from list with constructor X oldz and names it p. But...
You need to describe how to behave when your list get changed after map (res p) is applied.
If all your "changes" to list should be made only based on initial values of list and be applied in order from first element to last:
myf ps = (buildPlan ps) ps where
buildPlan [] = id
buildPlan (x:xs) = map (res x) . buildPlan xs
Some may prefer:
myf ps = changesPlan ps where
change x = map (res x)
changesPlan = foldr (.) id (map change ps)
If your "changes" to list should take changes from previous map (res x) (in non-func language while walking through list you change all elements even those which will be taken at next iteration):
myf ps0 = rebuildFrom 0 ps0 where
rebuildFrom n ps | n >= length ps = ps
rebuildFrom n ps = rebuildFrom (n+1) ps' where
x = ps !! n
ps' = map (res x) ps