Вы находитесь на странице: 1из 5

Hints for Revision: Functional Programming

Topics for the exam:


1. General programming questions. (Do you know how to write a simple program in a functional
language?)
double :: Int -> Int
double x = x*2

2. + 3 Programming questions using recursion/list comprehension/higher order functions. (Note


there are a number of lab questions on this, where you practice changing from one to another
technique.)
recursive (answer: calls itself)
type
Base case
Recursive case x = recursive case x
higher order (has an argument or output that is a function)
applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)
polymorphic - a function is polymorphic if it behaves uniformly for all types. i.e typeclass
length :: [a] -> Int
length [] = 0
length (_:xs) = 1 + length xs
-i.e length will work for all arrays.

4. Types and Typeclasses. Please revise the handout for Types and Typeclasses, and the
corresponding lab sheet.
:t is used to check type
Eq is used for types that support equality testing.
Ord covers all the standard comparing functions such as >, <, >= and <=
Num is a numeric typeclass. Its members have the property of being able to act like numbers.

5. Advanced programming question: (either using IO, or data).


Your should revise this indepth – past exam
6. General Questions about declarative Programming.
Declarative programming is both functional and logical , declarative programming is different
from imperial in the sense that you write the program what you want it to do but not how
you want to do it.

Advantages:
1. Avoids states, side effects and mutation of data – inputs will always produce the same
outputs.
2. Easier to write + read– tell the program what and not how.
3. Code is much easier to reuse, think of functions or prolog – same data functions build on
top of eachother, knowledge bases build on top of eachother.

Disadvantages:
1. Difficult to modify code precisely, have to work around the tools instead of working with
the tools – have to mitigate any imperfections and rely on underlying language

More detailed information:

Re 1. Hint: always give the type information of a program. That is already the first mark.
Here an old exam question:
Type information:
count:: [Char] -> Int
Using recursion:
count [ ] = 0
count (x:xs) = if isDigit x
then 1 + count xs
else count xs
Using list comprehension:
count xs = length ([x| x <- xs, isDigit x])
Using higher order functions [was not in the question, just added for completeness]
count xs = length (filter isDigit xs)

Re 4. Types/Type classes:
Jan 2017, question 1 (e):
i) Type of: ([True, False], '1') is ([Bool], Char)
ii) most general type of swap function: (a,b) -> (b,a)
iii) most general type of g x y = x < y is: Ord a => a -> a -> Bool.
[The function g can compare two arguments of an arbitrary type, provided in the type we can
compare two elements, [i.e. of any type in Ord]].
HINTS PROLOG part 2

Unification of two terms, "do the following two terms unify". [In case they unify, we would also like
to see the variable instantiation(s) and make them unify, in case they do not unify, I recommend to
give justification. Reason: this way, I see whether you have understood, it says much more than just
"yes/no"

ALGORITHM OF UNIFICATION
1. If term1 and term2 are constants, then term1 and term2 unify if and only if they are the
same atom, or the same number.

2. If term1 is a variable and term2 is any type of term, then term1 and term2 unify, and term1 is
instantiated to term2 . Similarly, if term2 is a variable and term1 is any type of term, then
term1 and term2 unify, and term2 is instantiated to term1 . (So if they are both variables,
they’re both instantiated to each other, and we say that they share values.)

3. If term1 and term2 are complex terms, then they unify if and only if:
1. They have the same functor and arity, and
2. all their corresponding arguments unify, and
3. the variable instantiations are compatible. (For example, it is not possible to
instantiate variable X to mia when unifying one pair of arguments, and to instantiate
X to vincent when unifying another pair of arguments .)

4. Two terms unify if and only if it follows from the previous three clauses that they unify.

PROLOG OCCURS CHECK - IN ADDITION UNIFICATION OF FATHER(X), X would produce an infinite


evaluation in Prolog but the rules of unification:
Following the rules of unification:
A standard unification algorithm would say: “No” No matter what you choose, the two terms
cannot possibly be made the same, for the term on the left will always be one symbol longer
than the term on the right
FOLLOWING PROLOG:
It would evaluate x as father(father(father(father… infinitely THEREFORE at some point it
must unify so YES – older implementations will crash others will do an occurs check.

So it depends, there are three responses to the question answer given by the standard
unification algorithm (which is to say no), the response of older Prolog implementations
(they use up the available memory), and the answer given by sophisticated Prolog
implementations (which is to say yes, and return a finite representation of an infinite
term). In short, there is no ‘right’ answer to this question. What is important is that you
understand the difference between standard unification and Prolog unification, and know
how the Prolog implementation that you work with handles such examples. READ LINK
3. Modification of this question, "what is the result of the following query." See exam
questions, easy to check, just type the query into Prolog. Similary: the different between
different forms of equality, this was one of the late chapters.
Literally follow a tree or evaluate on paper to show working on the knowledge base.
Take time to read it carefully.

4. Proof trees, and how they work – learn this my dude.


Prolog execution tree (or Prolog search tree, Prolog proof tree)
It is a tree to show the execution of a prolog program.
We represent the current un-executed goals in each tree note. An arrow represents
one step of computation. The results of unification are displayed beside of
corresponding arrows.
The root of an execution tree is the initial query. A tree branch stops when either the
program fails or successes.
father(john,ben).
father(john,steve).
father(steve,chris).
father(chris,adam).
father(steve,tom).
grandfather(X,Z) :- father(X,Y), father(Y,Z).

When we run
?- grandfather(G,chris).
a Prolog the execution tree will be constructed as follows:

?- grandfather(G, chris).

G=X Z=chris

?- father(X, Y), father(Y, chris).

X=john Y=ben (using 1) X=john, Y=steve (using 2)

?- father(ben, chris). ?- father(steve,chris).

Fail
4. Recursion and tail recursion. often a program can be turned into a tail recursive program by using
an addtional argument that stores intermediate results.
Base case and recursive case as always
Use counter in recursion in order to store data in the middle and then use the tail to be more
efficient ( look it up)

5. Cut! Negation by Failure.


The use of cut and a fail in a clause forces the failure of the whole predicate, and is a
technique termed cut-fail. It is useful to make a predicate fail when a condition (which may
be a call to an arbitrary predicate) succeeds. An example of cut-fail combinations is
implementing in Prolog the predicate ground/1, which succeeds if no variables are found in a
term, and fails otherwise. The technique is recursively traversing the whole term, and forcing
a failure as soon as a variable is found:

ground(Term):- var(Term), !, fail.


ground(Term):-
nonvar(Term),
functor(Term,F,N),
ground(N,Term).

ground(0,T).
ground(N,T):-
arg(N,T,Arg),
ground(Arg),
N1 is N-1,
ground(N1,T).

6. Application to puzzles, games. Here normally some instruction is given.


-hard work my dude
Also note: there will always be some questions which will look very familiar to you- so start with
those - and some question which are a sense new to you. However stay calm, normally some
detailed instruction is given, just read....

Вам также может понравиться