Fortran pass by reference pass by value homework - fortran

I had a question on a hw that I got wrong and was wonder if someone could explain it.
Don't worry class is over just wanted to know why it's wrong. I asked a few other student and they had the same answer I had as well. I also look on line but all the examples I found are swap functions the X=1 is confusing me.
SUBROUTINE TEST(X,Y,Z)
X=1
Z=X+Y
RETURN
END
N=2
CALL TEST ( N,N,M)
WHAT WILL M BE IF PASSED BY REFERENCE?
WHAT WILL M BE IF PASSED BY VALUE-RESULT?
I got 3 for the first and 4 for the second question.

If you are passing by reference,
X=2, Y=2 when the subroutine is entered.
Then X gets set to 1, which will change Y to 1 as well since they share the same memory location, right? So that would make (X+Y) = 2 ==> Z = 2.
M=2.
By value:
X=2, Y=2, but then X get sets to 1 but that doesn't change Y since this is by value. That makes Z = 3.
M =3.

Related

Prolog - How to get the sum of a list's elements?

I'm very new to prolog and I am trying to write a little program that, given a list, returns the sum of the list's elements. Following all the examples I've seen led me to a solution that looks like this:
addup([],0).
addup([FirstNumber | RestOfList], Total) :-
addup(RestOfList, TotalOfRest),
Total is FirstNumber + TotalOfRest.
But when I test that solution with these values:
?- addup([1,2,3,4],0).
I just get garbage values from it like _34521.
Then I tried a second solution that looks like this:
sum([], 0).
sum([H|T], N):-
X is H+N,
sum(T, X).
This one is able to add up the numbers correctly, but it is unable to pass the final value of X, which is the true answer, into N. So for the test case:
?- sum([1,2,3,4], 0).
I get an answer of 6, the final value of N, and the second-to-last value of X, instead of 10, the final value of X. Any help and/or explanations of why neither of these solutions work would be greatly appreciated. Thanks.
Firstly, the sum of an empty list is 0 - this is the base case, which you already had.
Secondly, the sum N of an element H and a list T is the sum of the list T added to H. Prolog operates on unification, so this says that N is unified with the sum of H and T, where the sum of T is unified with X using sum(T,X).
sum([], 0).
sum([H|T], N):-
sum(T, X),
N is X + H.
This gives:
?- sum([1,2,3,4],N).
N = 10.
In your original question, ?- sum([1,2,3,4], 0). actually says "this is true if the sum of the list [1,2,3,4] is 0" - you need to pass a variable as the second argument to sum to be unified with the answer.
Further information:
_34521 is a representation of an unbound variable - this says that there is a variable, but that it has not yet been unified with a value.
Secondary consideration:
For a suitably long list, the implementation above will run out of stack space, as each frame of the recursion must be stored, so that the addition can happen from the bottom up. In order to prevent a stack error, we can use a tail-recursive accumulator like so:
sum(L, N):-
sum(L, 0, N).
sum([],N,N).
sum([H|T],A,N) :-
A1 is A + H,
sum(T,A1,N).
... which retains the signature of the original method, wrapping sum/3. As there is no choice-point in the body of the rule (given that A + H is always the same for a given A and H, and the list is either empty or not), Prolog will discard each frame as it leaves scope (as there is nothing more to be done with it) and, on completion, will return to the original caller.
Simplified stack for sum([1,2,3],N) in each instance:
non-tail-recursive:
rest-of-stack
rest-of-stack,sum([1|[2,3]],_1001)
rest-of-stack,sum([1|[2,3]],_1001),sum([2|[3]],_1002)
rest-of-stack,sum([1|[2,3]],_1001),sum([2|[3]],_1002),sum([3|[]],_1003)
rest-of-stack,sum([1|[2,3]],_1001),sum([2|[3]],_1002),sum([3|[]],_1003),sum([],0)
rest-of-stack,sum([1|[2,3]],_1001),sum([2|[3]],_1002),sum([3|[]],3)
rest-of-stack,sum([1|[2,3]],_1001),sum([2|[3]],5)
rest-of-stack,sum([1|[2,3]],6)
rest-of-stack
tail-recursive:
rest-of-stack
rest-of-stack,sum([1,2,3],_1001)
rest-of-stack,sum([1|[2,3]],0,_1001)
rest-of-stack,sum([2|[3]],1,_1001)
rest-of-stack,sum([3|[]],3,_1001)
rest-of-stack,sum([],6,6)
rest-of-stack
Note that the tail-recursive stack has a limited depth for any length of list (dependent on what is calling it), where the non-tail-recursive stack goes to a depth directly proportional to the length of the list.
Thus, a call such as N is 10^7,length(L,N),maplist(=(1),L),sum(L,N). (as raised by #false) will likely fail without tail-recursion, and likely succeed with it.

FORTRAN 77 NEQNF IMSL Solver, 2 variables, 6 equations

I am trying to use NEQNF to solve a system of 6 non linear equations. I need to determine 2 variables to solve my system. According to description i need to define "N" which is the length of "X"(variables) AND "F"(equations).
Does this mean that i can use this solver only if X=F? Because N is defindes as an integer in the example given below in the description.
Or can i define N as a vector? How does declaration of N supposed to look like in this case?
From the link you gave:
X – The point at which the functions are evaluated. (Input) X should
not be changed by FCN.
F – The computed function values at the point X. (Output)
N — Length of X and F.
X and F are vectors of length N (scalar!). X is the input to FCN, and F the output. So I would guess that F is (generally) not equal to X.

tail recursive implementation of a factorial function

I am reading the book by jason and do not quite understand the following program:
let fact2 i =
let rec loop accum i =
if i = 0 then
accum
else
loop (i * accum) (i - 1)
in
loop 1
How is accum initialized?
What is the meaning of the last two lines (i.e. in loop 1)? loop has two parameters. why only one is passed here (i.e. loop 1).
Thank you very much!!!
I think that it's a mistake in implementation. Last line should be
loop 1 i
Integer 1 initialises accum from loop function and i initializes i in the same function.
Note that the lines starting with let rec loop accum i define a function. So accum is initialized when the function is called. This happens in the last line. As Kakadu points out, there's a transcription error in your post. The last line should say loop 1 i which (in essence) initializes accum to 1.
I think you have an extra "i" in the first line. That makes fact2 take an extra argument which is never used. Instead it should read:
let fact2 =
The last line that says "loop 1" is often called a partial application.
Ocaml usually uses curried functions, so another way of thinking of it is that loop actually takes one parameter and returns a function which in turn takes another parameter and returns an int.
In this particualar case, the type of (loop 1) is int -> int meaning it takes an int and returns an int. The type of loop is int -> int -> int meaning it takes an int and return an int -> int. It can also be written more explicitly as int -> (int -> int) since -> is right-associative.
To answer the other question, accum is initialized by passing 1 to loop.
Here is more information on currying: http://en.wikipedia.org/wiki/Currying
And of course, adding another "i" as others are suggesting would also work, but then you'd still be confused when others left it out.
It may help to think of let f x y = ... as being equivalent to let f = fun x -> fun y -> ...
And of course let f x = g x is the same as let f = g except the former will only work when g is a function.

Checking for concatenation in Prolog

This is another prolog task that I can't solve at this moment. I have to write a predicat p(X,Y), where X is list of lists of number and Y is a list of numbers. The predicat has to verify:
1) if X can be presented as a concatenation between 2 elements from Y.
2) X has a odd number of elements.
3) Sum of all elements in X is last element in Y.
Maybe as a separate tasks 2, 3 could be written easy. Problem is at 1)
Thank you in advance. I feel sorry for posting such an easy tasks, but prolog really drives me crazy. I have read all my lections over and over again. But the situation is similar to this:
school: 3+x=5, x = ?
exam: cos(x+y+z) + lim (5x+y)/t = .... If you know what I mean. Thank you once again!
Checking for concatenations is done with append/3, which is more commonly used to build them but like many Prolog predicates works "in the opposite direction" as well. More specifically, append(A,B,C) checks whether C is the concatenation of A and B. So,
member(A, Y),
member(B, Y),
append(A, B, X)
checks whether there is a element A in Y and a element B in Y such that their concatenation unifies with X.
(Note that this does not check whether A and B are distinct elements of Y.)

How does Ocaml variable scope work?

I'm starting learning Ocaml, using hickey book, and I'm stuck on Exercise 3.4, part 9
let x x = x + 1 in x 2
The result of the operation is 3, but I don't understand why?
When you write let x x = ... you are defining a function called x which binds the name x to its argument.
Since you used let instead of let rec, the function doesn't know its own name, so as far as it knows, the only x worth knowing about is the one passed in as an argument.
Therefore when you call the function with x 2, it binds the value 2 to the name x and evaluates x+1, getting 3 as the result.