Return values in Prolog - math

I'm supposed to write a predicate that does some math stuff. But I don't know how to pass numbers or return numbers.
Maybe you can give me an example?
Let's say a predicate divide/2 that takes two numbers a and b and returns a/b.

Yes, you pass numbers in in some arguments, and you get the result back in some other argument(s) (usually last). For example
divide( N, D, R) :-
R is N / D.
Trying:
112 ?- divide(100,5,X).
X = 20.
113 ?- divide(100,7,X).
X = 14.285714285714286.
Now, this predicate is divide/3, because it has three arguments: two for inputs and one for the output "information flow".
This is a simplified, restricted version of what a Prolog predicate can do. Which is, to not be that uni-directional.
I guess "return" is a vague term. Expression languages have expressions e-value-ated so a function's last expression's value becomes that function's "return" value; Prolog does not do that. But command-oriented languages return values by putting them into some special register. That's not much different conceptually from Prolog putting some value into some logvar.
Of course unification is more complex, and more versatile. But still, functions are relations too. Predicates "return" values by successfully unifying their arguments with them, or fail to do so, as shown in the other answer.

Prolog is all about unifying variables. Predicates don't return values, they just succeed or fail.
Typically when a predicate is expected to produce values based on some of the arguments then the left-most arguments are inputs and the right-most are the outputs. However, many predicates work with allowing any argument to be an input and any to be a output.
Here's an example for multiply showing how it is used to perform divide.
multiply(X,Y,Z) :- number(X),number(Y),Z is X * Y.
multiply(X,Y,Z) :- number(X),number(Z),X \= 0,Y is Z / X.
multiply(X,Y,Z) :- number(Y),number(Z),Y \= 0,X is Z / Y.
Now I can query it like this:
?- multiply(5,9,X).
X = 45 .
But I can easily do divide:
?- multiply(5,X,9).
X = 1.8 .
It even fails if I try to do a division by 0:
?- multiply(X,0,9).
false.

Here's another approach. So let's say you have a list [22,24,34,66] and you want to divide each answer by the number 2. First we have the base predicate where if the list is empty and the number is zero so cut. Cut means to come out of the program or just stop don't go to the further predicates. The next predicate checks each Head of the list and divides it by the number A, meaning (2). And then we simply print the Answer. In order for it to go through each element of the list we send back the Tail [24,34,66] to redo the steps. So for the next step 24 becomes the Head and the remaining digits [34,66] become the Tail.
divideList([],0,0):-!.
divideList([H|T],A,Answer):-
Answer is H//A,
writeln(Answer),
divideList(T,A,_).
?- divideList([22,24,34,66],2,L).
OUTPUT:
11
12
17
33

Another simpler approach:
divideList([],_,[]).
divideList([H|T],A,[H1|L]):-
H1 is H//A,!,
divideList(T,A,L).
?-divideList([22,4,56,38],2,Answer).
Answer = [11, 2, 28, 19]

Related

How to return in prolog all elements from right to left greater than an integer in one predicate?

I have to write a code that return all elements from a given list which are strictly greater than a given integer, it returns from left to right. I cannot use recursion or any other function except the built-in functions: append/3, append/2, member/2, select/3, reverse/2, findall/3, bagof/3, setof/3, sumlist/2
Example case:
greater_list([1,9,2,8,3,7,12],7, X).
X = 12 ? ;
X = 8 ? ;
X = 9 ? ;
no
I can write it with recursion or help predicates, but without them I do not know how to start. I could use findall/3 but it would not return element by elements, but a list of elements greater than that given number.
I can write it with recursion or help predicates, but without them I do not know how to start.
I would be interested in how you think you can solve this with helper predicates but not without.
But for starting, consider this: What you need to do is to enumerate certain elements of the list. That is, enumerate elements of the list that have some property.
So to start, you need to know how to enumerate elements of the list. Once you know how to do that, you can worry about the property that they must fulfill.
You can enumerate list elements using member/2:
?- member(X, [1,9,2,8,3,7,12]).
X = 1 ;
X = 9 ;
X = 2 ;
X = 8 ;
X = 3 ;
X = 7 ;
X = 12.
Now, we want to enumerate elements, but only those that fulfill the property X > 7. This is equivalent to saying that "X is a member of the list, and X > 7". In Prolog, (something like) "and" is written with a comma (,):
?- member(X, [1,9,2,8,3,7,12]), X > 7.
X = 9 ;
X = 8 ;
X = 12.
Your predicate is supposed to take a variable limit, not hardcode the limit of 7. This will be similar to:
?- Limit = 7, member(X, [1,9,2,8,3,7,12]), X > Limit.
Limit = 7,
X = 9 ;
Limit = 7,
X = 8 ;
Limit = 7,
X = 12.
Packing this up in a predicate definition will get you started. It looks like the order in which the elements are enumerated here is the reverse of what is intended. Maybe one of your built-ins helps you with this...
(Also, if you know how to write this using findall, you can then use member to enumerate the elements of the findall'ed list. But you shouldn't get in the habit of using findall in general, and especially not if the required solution isn't even a list. Beginners and bad teachers tend to over-emphasize putting things in lists, because that is what you have to do in lesser programming languages. Free yourself from thinking in other languages, even if your teacher can't.)
You can use findall/3 to get a list of the sought elements and then use member/2 to enumerate the members of that list:
greater_list(L,Limit,X) :-
findall(E,(member(E,L),E>Limit),Es),
member(X,Es).
Then:
?- greater_list([1,9,2,8,3,7,12],7, X).
X = 9 ;
X = 8 ;
X = 12.
?- greater_list([],7, X).
false.
And in a roundabout way:
?- findall(X, greater_list([1,9,2,8,3,7,12],7, X), Xs).
Xs = [9, 8, 12].
NB. this relies on recursion, I didn't notice that you couldn't use it at first
Instead of reversing the list, you can write the predicate without other helper predicates and consider first the recursive case. This ensures the first element to be checked against N will be the last element of the list.
greater_list([_|L], N, X) :- greater_list(L,N,X).
greater_list([X|_], N, X) :- X > N.
The lack of a clause for the empty list means that the predicate fails for empty lists.
The first clause above declares that X is item from a list that is greater than N if it is such an item in the sublist L.
The second clause, tried on backtracking, declares that the predicate is also true if X is the front element of the list and it is greater than N.
Both clause make Prolog search first in the sublist, and only when backtracking, consider the values stored in the list. As backtracking unfolds from deeper recursion levels first, the rule will be applied in a way that checks the last element first, then second to last, etc.
[eclipse 2]: greater_list([1,9,2,8,3,7,12],7, X).
X = 12
Yes (0.00s cpu, solution 1, maybe more) ? ;
X = 8
Yes (0.00s cpu, solution 2, maybe more) ? ;
X = 9
Yes (0.00s cpu, solution 3, maybe more) ? ;
No (0.00s cpu)

DFA to mathematical notation

Let's say I have a DFA with alphabet {0,1} which basically accepts any strings as long as there is no consecutive 0's (at most one 0 at a time). How do I express this in a mathematical notation?
I was thinking of any number of 1's followed by either one or none 0's, then any number of 1's..... but couldn't figure out the appropriate mathematical notation for it.
My attempt but obviously incorrect since 1010 should be accepted but the notation does not indicate so:
As a regular expression you could write this as 1*(01+)*0?. Arbitrary many ones, then arbitrary many groups of exactly one zero followed by at least one one, and in the end possibly one zero. Nico already wrote as much in a comment. Personally I'd consider such a regular expression sufficiently formal to call it mathematical.
Now if you want to write this using exponents, you could do something like
L = {1a (0 11+bi)c 0d mod 2 | a,bi,c,d ∈ ℕ for 1≤i≤c}
Writing a bit of formula in the exponents has the great benefit that you don't have to split the place where you use the exponent and the place where you define the range. Here all my numbers are natural numbers (including zero). Adding one means at least one repetition. And the modulo 2 makes the exponent 0 or 1 to express the ? in the regular expression.
Of course, there is an implied assumption here, namely that the c serves as a kind of loop, but it doesn't repeat the same expression every time, but the bi changes for each iteration. The range of the i implies this interpretation, but it might be considered confusing or even incorrect nonetheless.
The proper solution here would be using some formal product notation using a big ∏ with a subscript i = 1 and a superscript c. That would indicate that for every i from 1 through c you want to compute the given expression (i.e. 011+bi) and concatenate all the resulting words.
You could also give a recursive definition: The minimal fixpoint of the following definition
L' = {1, 10} ∪ {1a 0 b | a ∈ ℕ, a > 0, b ∈ L'}
is the language of all words which begin with a 1 and satisfy your conditions. From this you can build
L = {ε, 0} ∪ L' ∪ {0 a | a ∈ L'}
so you add the empty word and the lone zero, then take all the words from L' in their unmodified form and in the form with a zero added in front.

(Prolog) Get sum of variables without list

very new to Prolog and I'm absolutely awful at it.
I am trying to get a sum for all the marks received on assignments, and return it. The sum predicate must be of the form sumAssignments(S).
Here's the knowledge base I've made:
assignment(1, A).
assignment(2, B).
assignment(3, C).
assignment(4, D).
assignment(5, E).
...Where assignment(1, A) means that assignment 1 has a variable grade A (could be 70, could be 50, etc.).
Here is my attempt at getting the sum, just for the first two assignments for testing purposes:
sumAssignments(S) :- assignment(1, A), assignment(2, B), S=A+B.
That always returns yes. The key here is I can't use lists.
I found out that only constants belong in predicates, so instead of assignment(1, A). we would find an arbitrary number to represent 'A', in this case maybe 67 or 100: assignment(1, 67). The summation works fine after doing that.

Evaluating an expression in maple

I have a complicated expression in maple which depends on four real parameters, say a,b,c,d. Let us call this expression f(a,b,c,d). This expression consists of derivatives, definite and indefinite integrals of hyperbolic functions. By indefinite integral I mean expressions like Int(g(x),x). The expression f is to big for maple to write out, and I would therefore like to evaluate it numerically for different values of a,b,c and d. I tried doing evalf(value(f(a1,b1,c1,d1)), but this never terminates in maple, which I guess means that maple first tries to simplify f algebraically and then plugs in the real values a1,b1,c1, and d1.
Could someone please help me with this?
After the symbolic manipulation Maple will return an expression in terms of other variables for example:
diff(x^2 + 2, x); will return "2 x"
now if you write evalf(%), it will not be able to evaluate to any numerical value because it does not know the value of x. Therefore you have to first use subs() function to substitute the value of x where you want to evaluate the resulting expression.
Thus, in your case it will be subs([x=2, y=5], f(a, b, c, d)) assuming that the evaluated expression has variables x and y.
Remove the value command. It tries to evaluate your integrals symbolically, which is probably impossible. Just use evalf.

Prolog =:= operator

There are some special operators in Prolog, one of them is is, however, recently I came across the =:= operator and have no idea how it works.
Can someone explain what this operator does, and also where can I find a predefined list of such special operators and what they do?
I think the above answer deserves a few words of explanation here nevertheless.
A short note in advance: Arithmetic expressions in Prolog are just terms ("Everything is a term in Prolog"), which are not evaluated automatically. (If you have a Lisp background, think of quoted lists). So 3 + 4 is just the same as +(3,4), which does nothing on its own. It is the responsibility of individual predicates to evaluate those terms.
Several built-in predicates do implicit evaluation, among them the arithmetic comparsion operators like =:= and is. While =:= evaluates both arguments and compares the result, is accepts and evaluates only its right argument as an arithmetic expression.
The left argument has to be an atom, either a numeric constant (which is then compared to the result of the evaluation of the right operand), or a variable. If it is a bound variable, its value has to be numeric and is compared to the right operand as in the former case. If it is an unbound variable, the result of the evaluation of the right operand is bound to that variable. is is often used in this latter case, to bind variables.
To pick up on an example from the above linked Prolog Dictionary: To test if a number N is even, you could use both operators:
0 is N mod 2 % true if N is even
0 =:= N mod 2 % dito
But if you want to capture the result of the operation you can only use the first variant. If X is unbound, then:
X is N mod 2 % X will be 0 if N is even
X =:= N mod 2 % !will bomb with argument/instantiation error!
Rule of thumb: If you just need arithmetic comparison, use =:=. If you want to capture the result of an evaluation, use is.
?- 2+3 =:= 6-1.
true.
?- 2+3 is 6-1.
false.
Also please see docs http://www.swi-prolog.org/pldoc/man?predicate=is/2
Complementing the existing answers, I would like to state a few additional points:
An operator is an operator
First of all, the operator =:= is, as the name indicates, an operator. In Prolog, we can use the predicate current_op/3 to learn more about operators. For example:
?- current_op(Prec, Type, =:=).
Prec = 700,
Type = xfx.
This means that the operator =:= has precedence 700 and is of type xfx. This means that it is a binary infix operator.
This means that you can, if you want, write a term like =:=(X, Y) equivalently as X =:= Y. In both cases, the functor of the term is =:=, and the arity of the term is 2. You can use write_canonical/1 to verify this:
?- write_canonical(a =:= b).
=:=(a,b)
A predicate is not an operator
So far, so good! This has all been a purely syntactical feature. However, what you are actually asking about is the predicate (=:=)/2, whose name is =:= and which takes 2 arguments.
As others have already explained, the predicate (=:=)/2 denotes arithmetic equality of two arithmetic expressions. It is true iff its arguments evaluate to the same number.
For example, let us try the most general query, by which we ask for any solution whatsoever, using variables as arguments:
?- X =:= Y.
ERROR: Arguments are not sufficiently instantiated
Hence, this predicate is not a true relation, since we cannot use it for generating results! This is a quite severe drawback of this predicate, clashing with what you commonly call "declarative programming".
The predicate only works in the very specific situation that both arguments are fully instantiated. For example:
?- 1 + 2 =:= 3.
true.
We call such predicates moded because they can only be used in particular modes of usage. For the vast majority of beginners, moded predicates are a nightmare to use, because they require you to think about your programs procedurally, which is quite hard at first and remains hard also later. Also, moded predicates severely limit the generality of your programs, because you cannot use them on all directions in which you could use pure predicates.
Constraints are a more general alternative
Prolog also provides much more general arithmetic predicates in the form of arithmetic constraints.
For example, in the case of integers, try your Prolog system's CLP(FD) constraints. One of the most important CLP(FD) constraints denotes arithmetic equality and is called (#=)/2. In complete analogy to (=:=)/2, the operator (#=)/2 is also defined as an infix operator, and so you can write for example:
| ?- 1 + 2 #= 3.
yes
I am using GNU Prolog as one particular example, and many other Prolog systems also provide CLP(FD) implementations.
A major attraction of constraints is found in their generality. For example, in contrast to (=:=)/2, we get with the predicate (#=)/2:
| ?- X + 2 #= 3.
X = 1
| ?- 1 + Y #= 3.
Y = 2
And we can even ask the most general query:
| ?- X #= Y.
X = _#0(0..268435455)
Y = _#0(0..268435455)
Note how naturally these predicates blend into Prolog and act as relations between integer expressions that can be queried in all directions.
Depending on the domain of interest, my recommendition is to use CLP(FD), CLP(Q), CLP(B) etc. instead of using more low-level arithmetic predicates.
Also see clpfd, clpq and clpb for more information.
Coincidentally, the operator =:= is used by CLP(B) with a completely different meaning:
?- sat(A =:= B+1).
A = 1,
sat(B=:=B).
This shows that you must distinguish between operators and predicates. In the above case, the predicate sat/1 has interpreted the given expression as a propositional formula, and in this context, =:= denotes equality of Boolean expressions.
I found my own answer, http://www.cse.unsw.edu.au/~billw/prologdict.html
Its an ISO core standard predicate operator, which cannot be bootstrapped from unification (=)/2 or syntactic equality (==)/2. It is defined in section 8.7 Arithmetic Comparison. And it basically behaves as follows:
E =:= F :-
X is E,
Y is F,
arithmetic_compare(=, X, Y).
So both the left hand side (LHS) and right hand side (RHS) must be arithmetic expressions that are evaluted before they are compared. Arithmetic comparison can compare across numeric types. So we have:
GNU Prolog 1.4.5 (64 bits)
?- 0 = 0.0.
no
?- 0 == 0.0
no
?- 0 =:= 0.0.
yes
From Erlang I think it could be good to annotate that as syntax are mostly look alike to Prolog.
=:= expression is meaning of exactly equal.
such as in JavaScript you can use === to also see if the type of the variables are same.
Basically it's same logic but =:= is used in functional languages as Prolog, Erlang.
Not much information but hope it could help in some way.
=:= is a comparison operator.A1 =:= A2 succeeds if values of expressions A1 and A2 are equal.
A1 == A2 succeeds if terms A1 and A2 are identical;

Resources