Not sure how to start this off, any suggestions?
Define a SCHEME function, named (eval-postfix p), that will take postfix expression (stored in a list of integers representing operands and characters representing operators), evaluate that expression, and return the result.
Your function should support the operations of addition (#+), subtraction (#-), multiplication (#*), divi- sion(#/), and exponentiation(#\ˆ).
You may want to work incrementally by starting with a function that takes a character representing an operator and can pop two operands off of a stack, evaluate the operator and push the result back on the stack. Next you can add a function that evaluates a postfix expression by pushing operands onto the stack and evaluating operators when encountered. Note, you may want to use the number? function to determine whether an item in the list is an operand or an operator.
Make a function that executes a single instruction on a stack, and returns the changed stack:
(define (postfix-execute-one instruction stack)
...)
it should check if instruction is number? or a symbol like '+. If it's a number you can just return (cons instruction stack) to push it, if it's an operator you need to pop 2 items off the stack, add them (or subtract them) and then push that on the stack and return.
Then you can make
(define (postfix-execute-all instructions stack)
...)
which recursively loops over the list of instructions, executing each one using the helper function defined earlier, until it reaches null?. Then it can return the final stack.
This is the suggested starting point from your description spelled out in more detail.
It's a good starting point, so stick to it.
Write a function whose input is one operator and a stack:
operator: +
stack: |x y z w|
It should pop two operands:
operator: +
left operand: x
right operand: y
stack: |z w|
evaluate:
result: x + y = A
stack: |z w|
and return the stack with the result added on top:
|A z w|
When you're done with that (make sure you test with all five operators) you use this function to implement the full evaluation function.
Related
I want to append([],C,C) where C is a list containing some elements . Is it possible? I will append some list in C containing elements append (Found,C,C) if other condition is true.
And also i want to store final value in C to a variable D . How can I do that?
I want to append([],C,C) where C is a list containing some elements. Is it possible?
append([],C,C) is always true. An empty list combined with anything is that anything. Look what Prolog says when you attempt it:
?- append([],C,C).
true.
This true without any bindings tells you that Prolog established the proof but no new bindings were created as a result. This code would have the same result:
meaningless(_, _, _).
?- meaningless(everybody, X, Squant).
true.
This suggests your desire is misplaced. append([], C, C) does not do what you think it does.
I will append some list in C containing elements append (Found,C,C) if other condition is true. And also i want to store final value in C to a variable D. How can I do that?
Thinking in terms of "storing" and other operations implying mutable state is a sure sign that you are not understanding Prolog. In Prolog, you establish bindings (or assert facts into the dynamic store, which is a tar pit for beginners). Something similar could be achieved in a Prolog fashion by doing something like this:
frob(cat, List, Result) :- append([cat], List, Result).
frob(dog, List, List).
This predicate frob/3 has two in-parameters: an atom and a list. If the atom is cat then it will append [cat] to the beginning of the list. The threading you see going between the arguments in the head of the clause and their use in the body of the clause is how Prolog manages state. Basically, all state in Prolog is either in the call stack or in the dynamic store.
To give an example in Python, consider these two ways of implementing factorial:
def fac(n):
result = 1
while n > 1:
result = result * n
n = n - 1
This version has a variable, result, which is a kind of state. We mutate the state repeatedly in a loop to achieve the calculation. While the factorial function may be defined as fac(n) = n * fac(n-1), this implementation does not have fac(n-1) hiding in the code anywhere explicitly.
A recursive method would be:
def fac(n):
if n < 1:
return 1
else:
return n * fac(n-1)
There's no explicit state here, so how does the calculation work? The state is implicit, it's being carried on the stack. Procedural programmers tend to raise a skeptical eyebrow at recursion, but in Prolog, there is no such thing as an assignable so the first method cannot be used.
Back to frob/3, the condition is implicit on the first argument. The behavior is different in the body because in the first body, the third argument will be bound to the third argument of the append/3 call, which will unify with the list of the atom cat appended to the second argument List. In the second body, nothing special will happen and the third argument will be bound to the same value as the second argument. So if you were to call frob(Animal, List, Result), Result will be bound with cat at the front or not based on what Animal is.
Do not get mixed up and think that Prolog is just treating the last argument as a return value! If that were true, this would certainly not work like so:
?- frob(X, Y, [whale]).
X = dog,
Y = [whale].
What appears to have happened here is that Prolog could tell that because the list did not start with cat it was able to infer that X was dog. Good Prolog programmers aspire to maintain that illusion in their APIs, but all that really happened here is that Prolog entered the first rule, which expanded to append([cat], X, [whale]) and then unification failed because Prolog could not come up with an X which, having had [cat] prepended to it, would generate [whale]. As a result, it went to the second rule, which unifies X with dog and the second two arguments with each other. Hence Y = [whale].
I hope this helps!
This may be a stupid question but at Uni we were presented with a Prolog segment that multiplies arrays. It has 4 predicates of which one I cannot understand what it does or how to execute it. Can you give me any hint or explanation?
multiply([],_,[]).
multiply([V0|Rest], V1, [Result|Others]):-
multiply(Rest,V1,Others),
inner_product(V0,V1,Result).
I tried to run the predicate like this:
multiply([1,2],3,X).
multiply([[1,2]],[3],X).
multiply([[1,2]],3,X)
multiply([1,2],[3,2],X).
but everything returned false.
Is there anything I am doing wrong?
No information has been given about what kind of arguments are expected, but you can determine it by looking at the clauses for multiply:
multiply([],_,[]).
This indicates that the first and third arguments are lists, of some kind.
multiply([V0|Rest], V1, [Result|Others]):-
multiply(Rest,V1,Others),
inner_product(V0,V1,Result).
inner_product, though not defined as #CapelliC pointed out, indicates that V0 and V1 are vectors (or in prolog, lists of scalar quantities) of the same length by definition of an inner product. And the Result value will be a scalar.
So, for multiply(M1, V, Result). to succeed:
M1 must be a list of lists, or a matrix. Each inner list must be the same length and it must be a list of scalar values
V must be a list of scalar values, and of the same length as the inner lists of M1
Inferred by the recursion, Result will be a vector (a list) of scalar values and the list will have a length equal to the length of M1 (have the same number of scalars as M1 has vectors).
In other words, it's following the rules of standard matrix/vector multiplication.
Looking at all the test cases shown, they will all fail because none of them match all 3 criteria above.
multiply([1,2],3,X). % Fails item #1 above
% `3` isn't a vector/list
multiply([[1,2]],[3],X). % Fails item #2 above
% length of [3] isn't length of [1,2]
multiply([[1,2]],3,X) % Fails item #2 above
% `3` isn't a vector/list
multiply([1,2],[3,2],X). % Fails item #1 above
% `[1,2]` isn't a list of lists (matrix)
So they will all fail just on the basis of not matching the expected configuration of arguments that allow the predicate to succeed.
Try something like:
multiply([[1,2,3],[3,2,1]], [1,1,1], X).
You should get:
X = [6,6]
Here is what I have and the error that I am getting sadly is
Error: This function has type 'a * 'a list -> 'a list
It is applied to too many arguments; maybe you forgot a `;'.
Why is that the case? I plan on passing two lists to the deleteDuplicates function, a sorted list, and an empty list, and expect the duplicates to be removed in the list r, which will be returned once the original list reaches [] condition.
will be back with updated code
let myfunc_caml_way arg0 arg1 = ...
rather than
let myfunc_java_way(arg0, arg1) = ...
Then you can call your function in this way:
myfunc_caml_way "10" 123
rather than
myfunc_java_way("10, 123)
I don't know how useful this might be, but here is some code that does what you want, written in a fairly standard OCaml style. Spend some time making sure you understand how and why it works. Maybe you should start with something simpler (eg how would you sum the elements of a list of integers ?). Actually, you should probably start with an OCaml tutorial, reading carefully and making sure you aunderstand the code examples.
let deleteDuplicates u =
(*
u : the sorted list
v : the result so far
last : the last element we read from u
*)
let rec aux u v last =
match u with
[] -> v
| x::xs when x = last -> aux xs v last
| x::xs -> aux u (x::v) x
in
(* the first element is a special case *)
match u with
[] -> []
| x::xs -> List.rev (aux xs [x] x)
This is not a direct answer to your question.
The standard way of defining an "n-ary" function is
let myfunc_caml_way arg0 arg1 = ...
rather than
let myfunc_java_way(arg0, arg1) = ...
Then you can call your function in this way:
myfunc_caml_way "10" 123
rather than
myfunc_java_way("10, 123)
See examples here:
https://github.com/ocaml/ocaml/blob/trunk/stdlib/complex.ml
By switching from myfunc_java_way to myfunc_caml_way, you will be benefited from what's called "Currying"
What is 'Currying'?
However please note that you sometimes need to enclose the whole invocation by parenthesis
myfunc_caml_way (otherfunc_caml_way "foo" "bar") 123
in order to tell the compiler not to interpret your code as
((myfunc_caml_way otherfunc_caml_way "foo") "bar" 123)
You seem to be thinking that OCaml uses tuples (a, b) to indicate arguments of function calls. This isn't the case. Whenever some expressions stand next to each other, that's a function call. The first expression is the function, and the rest of the expressions are the arguments to the function.
So, these two lines:
append(first,r)
deleteDuplicates(remaining, r)
Represent a function call with three arguments. The function is append. The first argument is (first ,r). The second argument is deleteDuplicates. The third argument is (remaining, r).
Since append has just one argument (a tuple), you're passing it too many arguments. This is what the compiler is telling you.
You also seem to be thinking that append(first, r) will change the value of r. This is not the case. Variables in OCaml are immutable. You can't do anything that will change the value of r.
Update
I think you have too many questions for SO to help you effectively at this point. You might try reading some OCaml tutorials. It will be much faster than asking a question here for every error you see :-)
Nonetheless, here's what "match failure" means. It means that somewhere you have a match that you're applying to an expression, but none of the patterns of the match matches the expression. Your deleteDuplicates code clearly has a pattern coverage error; i.e., it has a pattern that doesn't cover all cases. Your first match only works for empty lists or for lists of 2 or more elements. It doesn't work for lists of 1 element.
I am aware how we can evaluate an expression after converting into Polish Notations. However I would like to know how I can evaluate something like this:
If a < b Then a + b Else a - b
a + b happens in case condition a < b is True, otherwise, if False a - b is computed.
The grammar is not an issue here. Since I only need the algorithm to solve this problem. I am able evaluate boolean and algebraic expressions. But how can I go about solving the above problem?
Do you need to assign a+b or a-b to something?
You can do this:
int c = a < b ? a+b : a-b;
Or
int sign = a < b ? 1 : -1;
int c = a + (sign * b);
Refer to LISP language for S-express:
e.g
(if (> a b) ; if-part
(+ a b) ; then-part
(- a b)) ; else-part
Actually if you want evaluate just this simple if statement, toknize it and evaluate it, but if you want to evaluate somehow more complicated things, like nested if then else, if with experssions, multiple else, variable assignments, types, ... you need to use some parser, like LR parsers. You can use e.g Lex&Yacc to write a good parser for your own language. They support somehow complicated grammars. But if you want to know how does LR parser (or so) works, you should read into them, and see how they use their table to read tokens and parse them. e.g take a look at wiki page and see how does LR parser table works (it's something more than simple stack and is not easy to describe it here).
If your problem is just really parsing if statement, you can cheat from parser techniques, you can add empty thing after a < b, which means some action, and empty thing after else, which also means an action. When you parsed the condition, depending on correctness or wrongness you will run one of actions. By the way if you want to parse expressions inside if statement you need conditional stack, means something like SLR table.
Basically, you need to build in support for a ternary operator. IE, where currently you pop an operator, and then wait for 2 sequential values before resolving it, you need to wait for 3 if your current operation is IF, and 2 for the other operations.
To handle the if statement, you can consider the if statement in terms of C++'s ternary operator. Which formats you want your grammar to support is up to you.
a < b ? a + b : a - b
You should be able to evaluate boolean operators on your stack the way you currently evaluate arithmetic operations, so a < b should be pushed as
< a b
The if can be represented by its own symbol on the stack, we can stick with '?'.
? < a b
and the 2 possible conditions to evaluate need to separated by another operator, might as well use ':'
? < a b : + a b - a b
So now when you pop '?', you see it is the operator that needs 3 values, so put it aside as you normally would, and continue to evaluate the stack until you have 3 values. The ':' operator should be a binary operator, that simply pushes both of its values back onto the stack.
Once you have 3 values on the stack, you evaluate ? as:
If the first value is 1, push the 2nd value, throw away the third.
If the first value is 0, throw away the 2nd and push the 3rd.
I'm having this exercise which asks to count how many values in a boolean list are true.
I typed this:
fun countt xs = foldl (fn (x,y) => if x=true then y=y+1) 0 xs;
which, apparently, is wrong. I'm getting the following error:
stdIn:54.21-54.24 Error: syntax error: deleting RPAREN INT0
Now, I've searched a bit and found out that RPAREN is a Syntax error. But i can't figure why there's a problem in the first place.
In a functional programming language, an if expression must have both then branch and an else branch (and they must both have the same type).
Your if expression only has a then branch.
Additionally, x=true always evaluates to the same value as x so you can just write if x then ... else ....
Finally, it looks like you're trying to write an assignment in the then branch. Remember that a foldl works by repeatedly passing the accumulator (y) to the function as it traverses the list with xs. So if you want to update the accumulator, all you have to do is return the updated value.
Just to complement the previous answer here are the suggested modifications:
fun countt xs = foldl (fn (x,acc) => if x then acc+1 else acc) 0 xs;
The term in parenthesis is the first argument to foldl, the value 0 is the seed value and the xs is the sequence that will be folded. The function takes a value and the current element of the sequence xs.
The function must return a value of the same type of 0, an integer.