Prolog - Declaring arithmetic clauses - math

A simple question, how would I go about declaring a clause which would produce the number specified +1 +2 and +3? I have tried:
addup(Thenumber,Thenumber+1).
addup(Thenumber,Thenumber+2).
addup(Thenumber,Thenumber+3).
but when I run it with say, Thenumber=5, it just returns 5+1 5+2 5+3. I have tried using 'is' to force it to evaluate but it doesn't seem to work. Any help would be appreciated.

Try this:
addup(X, Y) :- Y is X + 1.
or
addup(X, X+1).
and you question should be addup(2, X)
then X should be 3. If you want to parametrize your addup parameter just make it:
addup(X, Y, X + Y).
and ask with addup(5, 6, X).

Related

Prolog: Check predicate against every item in the list

Basically, I want to be able to check to see if at least one value in a list satisfies some predicate.
What I have so far:
need(x,y).
check_list(X,[H|T]) :-
need(H,X).
And so this works fine so long as I only have one value in the list. I'm not sure how to make it check the other values. When I try and use recursion I eventually find an element that satisfies the second predicate but it then goes back up the stack which will eventually cause it to be false.How can I make it 'break' essentially?
The backtracking you are seeing during recursion is Prolog attempting to find more ways for the predicate to succeed. This is a fundamental Prolog behavior and is what makes it useful. It seeks to find all of the solutions.
In your case, you only want to confirm one solution to the problem of, An element in the list that meets a specific criterion. For this, you could use a cut:
check_list(X, [H|_]) :-
need(X, H), !. % Don't backtrack after success
check_list(X, [_|T]) :-
check_list(X, T).
Or you could use once/1 which is specifically designed to handle cases where you only want a single solution:
check_list(X, [H|_]) :-
need(X, H).
check_list(X, [_|T]) :-
check_list(X, T).
check_list_once(X, L) :- once(check_list(X, L)).
Here is an example of what you can do.
I want to check is numbers are odd.
is_even(X) :-
X mod 2 =:= 0.
check_list(L, CL) :-
include(is_even, L, CL).
with result
?- check_list([1,2,3,4,5], L).
L = [2, 4].
?- check_list([1,3,5], L).
L = [].
You can use simple recursion:
need(x,y).
check_list(X,[H|T]) :-
( need(H,X) -> true;
check_list(X,T) ).
You can see in the examples below that this definition is deterministic:
?- check_list(y,[1,2,3]).
false.
?- check_list(y,[x,2,3]).
true.
?- check_list(y,[1,2,x]).
true.
?- check_list(Y,[1,2,x]).
Y = y.
?- check_list(Y,[1,2,3]).
false.
?- check_list(Y,[1,x,3]).
Y = y.
?- check_list(Y,[1,X,3]).
Y = y,
X = x.
?- check_list(Y,[1,2,3]), Y = x.
false.
?- check_list(Y,[1,2,3]), Y = y.
false.
?- check_list(Y,[1,2,3]).
false.
?- check_list(Y,[1,2,x]), Y = y.
Y = y.
Though if you want your queries to have uninstantiated variables e.g check_list(Y,[1,2,x]). and you add another fact need(x,z). Then:
?- check_list(Y,[1,2,x]).
Y = y.
Returns only one result and not Y = z. You could use if_/3 from library reif if you want a better definition of check_list/3.

Prolog arithmetic on tuples

The idea is as follows: Suppose I have a list P = [(1,0),(4,3)] or similar. I want to evaluate the polynomial that's defined by this list in the manner: 1X^0 + 4X^3.
To do this, I've written the following:
evaluate(P,X,Y) :- evaluate(P,X,Y,0).
evaluate([],_,S,S).
evaluate([P1,P2|Ps],X,Y,S) :-
S1 is S+P1*X^P2,
evaluate(Ps,X,Y,S1).
Which is supposed to succeed when Y is the sum of the polynomial P, given x=X.
The problem is that when I try and run this code, I get the error:
is/2: Arithmetic: `(',')/2' is not a function
But I have no idea where this is coming from or how to fix it.
I did try splitting the S1 is up in to its segments, but doing that didn't help.
EDIT: Ok, I found out that it's about the way the list is written down. How do I work with tuples in this way within the bounds of Prolog?
Your problem is that your data structure for each item in the list is a tuple as you noted and where you access the values of tuple in the list is not correct.
This
evaluate([P1,P2|Ps],X,Y,S) :-
should be
evaluate([(P1,P2)|Ps],X,Y,S) :-
Notice the parenthesis around P1,P2.
When I run with the change I get
?- evaluate([(1,0),(4,3)],5,Y).
Y = 501.
Also it is common to put the output arguments at the end,
evaluate_01(P,X,Y,0).
as
evaluate_01(P,X,0,Y).
and then change the other predicates as necessary.
evaluate_02(P,X,Y) :- evaluate_02(P,X,0,Y).
evaluate_02([],_,S,S).
evaluate_02([(P1,P2)|Ps],X,S,Y) :-
S1 is S+P1*X^P2,
evaluate_02(Ps,X,S1,Y).
As an interesting option, this can be done with maplist/3 and sumlist/2:
evaluate_poly(Poly, X, R) :-
maplist(evaluate_term(X), Poly, EvaluatedTerms),
sumlist(EvaluatedTerms, R).
evaluate_term(X, (Coeff, Power), TermValue) :-
TermValue is Coeff * (X ^ Power).

how to work backwards in a function in R

I was wondering if it would be possible to work backwards in a function in R in order to get a value for a variable that will output a known value.
For a simple example,
x<-5
afunction <- function(x,y) {
x*y
}
How can I get the value of y that will output a known value of say 15. That is, I want the the return of the function to be 3.
Is this possible?
Thank you.
If you are looking for the y value that makes afunction(x, y) equal 15, this is the same as finding the zeros of the following function:
g <- function(y) afunction(x, y) - 15
You can use uniroot to find zeros of a function:
uniroot(g, c(-100, 100))$root
# [1] 3
Note that you need to specify a range of y values for uniroot -- I've used [-100, 100] here.

Total Beginner: Python 3.4 spot the syntax error

When running the following code, I get an error as follows:
for (x in List[0] and y in range(0,11)):
^
SyntaxError: invalid syntax
I am very new to Python programming. When I try to run the iteration at the top I get the above error-message.
Could someone please kindly explain which part of the syntax is invalid?
The tiny arrow underneath seems to point to the colon.
Many thanks.
Syntax Error: The brackets are not necessary; use the following:
for x in List[0] and y in range(0, 11): ...
More Problems Although as in my comment, this won't necessarily work.
Merging the Arrays:
If you are trying to go through all values in List[0] and then in range(0, 11), do the following:
for x in (List[0] + range(0, 11)): ...
No Duplicates:
Or, if you want no duplicates, and ordering does not matter, use this:
for x in list(set(List[0] + range(0, 11))): ...
Going through all pairs:
Or, if you are trying to go through all pairs consisting of a value in List[0] and a value in range(0, 11), use the following:
for x in List[0]:
for y in range(0, 11):
...

Recursion help in OCaml

I'm trying to make a recursive function with Ocaml, but I keep getting the same error code.
let rec get x =
if x > 7 then
get x-7;;
And I get the very useful error message of:
Error: This expression has type int but an expression was expected of
type unit
I'm a complete beginner at OCaml, and studying it for a module at university.
And this is one of my assignments, and I'm a bit stuck!
I originally wanted to do it by a while loop, (as I'm a predominantly imperative programmer), but I couldn't get that to work, so I thought I'd try recursive!
Thanks
There's two problems with this code. First, the spacing of x-7 indicates that you would like to pass x - 7 to get, but it will actually be parsed as (get x) - 7. That's easily fixed with parentheses:
let rec get x =
if x > 7 then get (x - 7)
The second problem is that you don't have a second arm for the if, so the function doesn't have much of a chance of returning anything. (One arm if is taken to be of type unit, only useful for effects.)
You probably want to return something if x is less than 7, maybe:
let rec get x =
if x > 7 then get (x - 7) else x
Writing this with a while loop is possible, but you should understand that variables in OCaml are not mutable locations, only names. You'll have to introduce and manipulate mutable places explicitly:
let get x =
let y = ref x in
while !y > 7 do
y := !y - 7;
done;
!y
Hope that helps.

Resources