Lab Assignment4
Lab Assignment4
NAME : M.NAVEEN
ROLLNO : 422213
EXERCISE – 1:
Task 1:
Exercise 1
Explain what is wrong in the following expressions and propose a correction.
1. hd([]);
The hd function retrieves the head of a list, but passing an empty list [] will
result in a runtime exception since there is no head to retrieve. We should check if
the list is empty before using hd();
Correction:
val head = if null list then NONE else SOME(hd list);
2. explode (["toto"]);
The explode function expects a string as an argument, a list containing a
string (["toto"]) is passed, which is not valid.
Correction:
val result = explode("toto");
3. implode("a", "b");
The implode function expects a single list of characters as its argument, but
two strings ("a" and "b") are passed, which is not correct.
Correction:
implode(explode("ab"));
4. ["t"]:: ["o","p"];
:: operator is used to prepend an element to a list. For concatenating two lists
@ operator is used.
Correction:
val result = ["t"] @ ["o", "p"];
5. 6 @ 10;
The @ operator is used for concatenating lists, concatenating two integers
(6 and 10) is not valid.
Correction: val result = [6, 10];
Exercise 2
(3,4) and (3,4,5) have the same type? [3,4] and [3,4,5] have the same type?
Ans:
1. (3, 4) has type int * int
(3, 4, 5) has type int * int * int
2. Both [3, 4] and [3, 4, 5] are list of integers of type int list
Exercise 3
Consider the following definitions:
fun fact n = if n = 0 then 1
else n * fact (n - 1);
fun new_if (a, b, c) = if a then b else c;
Write a function new_fact using new_if. Explain why new_fact does not compute factorial?
Code:
fun new_fact n =
new_if (n = 0, 1, n * new_fact (n - 1));
Explanation:
The issue arises because new_if requires its arguments to be evaluated before it's
called, which can lead to a stack overflow due to infinite recursion when n is greater than 0.
Since n * new_fact (n - 1) is passed directly to new_if, it will evaluate new_fact (n - 1)
regardless of the condition and lead to infinite recursion.
Exercise 4
Link the variable x to the value 0 when constructing forms to match the following
expressions.
For example given the expression (false,"bonjour",0) the form (_,_,x) permits us to link x to 0
when we write: val (_,_,x) = (false, "bonjour" ,0).
i. {a=3, b=0, c=false} - record.
Ans: val {a=_, b=x, c=_} = {a=3, b=0, c=false}
fun main() =
let
val n = 5
val res = power_of_two n
in
if res then print(Int.toString n ^ " is a power of two\n")
else print(Int.toString n ^ " is not a power of two\n")
end
Exercise 6
What is the type of the following function, justify your answer.
fun f (x,y,z,t) =
if x=y then z + 1
Ans:
1. if x=y then z+1:
a. z is added to 1 so, z is of type int and hence the if statement is of type int.
b. x is compared with y so, x and y are of same type.
a. Since the if statement is of type int y+t must yield an integer and hence the types of
y ant t are int.
Exercise 7
Write 2 functions odd and even that define if an int is even or odd using mutual recursion.
Code:
fun
and
fun main() =
let
val a = 6 and b = 7
in
end
Output:
Exercise 8
What are the results of the following declaration and expression. Each one is independent.
1. val x = 2 and y = x + 1;
Ans: x = 1, y = 3, z = 2
Ans: val it = 3;
Exercise 9
What are the results of the following expressions evaluations.
Ans: val it = 7
3. let val t = x + 1 in let val x = x + 1 in x end end;
Ans: val it = 2
Exercise 10
Write a function insert that inserts an int in a (ascending) sorted list.
Code:
| insert a n =
let
val x::y = a
in
else [n] @ y
end
Output:
Exercise 11
Write a function interclass that interclasses 2 lists of (ascending) sorted int.
Code:
fun interclass (l1 : int list, l2 : int list) =
if l1 = [] then l2
else if l2 = [] then l1
val l2 = [1,3,5,6,7]
Output:
Exercise 12
Write a function insertion_sort that implements insertion sorting.
Code:
fun insertion_sort l : int list =
if l = [] then []
else let
in
end
if l = [] then [x]
val l = [2,3,4,1,8,7,5]
Exercise 13
Bubble sort
1. Define a function iteration that repeat the treatment of a data while a condition c this data is not
true.
2. Define a function is_sorted that returns true if a list is sorted, false otherwise.
Code:
fun iteration (treatment: 'a -> 'a, condition: 'a -> bool, data: 'a) : 'a =
fun bubble_pass [] = []
| bubble_pass (x::y::xs) =
let
end
val l = [4,3,2,1,7,6,4,2]
Output:
Exercise 14
Write a function that computes the subsets of a set. How to represent a set?
Code:
fun subsets [] = [[]]
| subsets (x::xs) =
let
in
end
Ouput:
Exercise 15
What is the type of C:
fun C f g x = f (g x);
Ans:
The function g must take an input of type a, so its type is g : 'a -> 'b for some type b.
The function f takes an argument of type b, so its type is f : 'b -> 'c for some type c.
val c = fn : ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c
Exercise 16
1. Write a function F that takes 2 parameters: a function O and a list l and processes the following
way:
Code:
fun f (O, l) =
let
in
process l
end
Output:
2. Write a function G that returns the elements of a list I that satisfy the condition cond. What is the
type of G? Why?
Type of G:
1. cond: A condition function of type 'a -> bool that checks whether an element should be
included.
Code:
| g (cond, x::xs) =
Output:
3. Using F and the function max that returns the maximum of 2 integers (write max) what is the
maximum of a list of int, for example (2,6,3, 15, 18, 1, 55, 22))?
Code:
fun f (O, l) =
let
in
process l
end
val l = [2,3,4,10,33,12]
Output:
4. Using F and the function conc that returns the concatenation of 2 strings (write conc) what is the
concatenation of all the strings of a list, for example ["a", "b", "c", "d")?
Code:
fun f (O, l) =
let
in
process l
end
Ouput:
5. Consider the function fold. What is its type?
Ans:
val fold = fn : ('a * 'b -> 'b) -> 'a list -> 'b -> 'b
Exercise 17
Consider the function f:
| f (x, a::aa) = if x(a) then a:: f (x, aa) else f(x, aa);
Let Te be the type of an expression e. We construct using f the following system of equations.
(4) ’b = T_{nil}
Ans:
b. For the base case the function returns nil and for other cases it returns f(x, aa) hence type
’b can be {nil, f(x,aa)}.
c. For base case the function f takes the argument (x, nil) so the type ’a can be T_x * T_{nil}
and for other cases is it T_x * T_{a::aa}.
Ans:
val f = fn : ('a -> bool) * 'a list -> 'a list
Exercise 18
Let consider f:
Let Te be the type of an expression e. We construct a set of equations from the definition of f. Write
this system and compute the type of f.
Set of Equations:
1. T_f = ’a -> ’b
2. ’a = T_x * T_{nil}
3. ’a = T_x * T_{a::aa}
4. ’b = T_{nil}
5. ’b = bool list
6. T_{x(a)} = bool
Type of f:
Exercise 19
1. Write a datatype COORDS that defines the coordinates of a point in 3D.
Code:
Output:
3. Using COORDS write a function distance that computes the distance between 2 points.
Code:
fun distance (Coords (x1, y1, z1), Coords (x2, y2, z2)) =
let
val x = x2 - x1
val y = y2 - y1
val z = z2 - z1
in
Math.sqrt(x * x + y * y + z * z)
end
Output:
Exercise 20
Create a datatype PERSON that defines a person defined by its name, frame, age and datebirth.
Ans:
name : string,
fname : string,
age : int,
Exercise 21
1. Create a reference variable i whose value is a reference to 10.
Ans: i := !i + 1;
Ans: i := !i – 1;
Ans: i := 20;
Exercise 22
while < expression > do < expression> has the following semantics in SML:
b. If the first expression is false, exit. Else, evaluate the second expression and go
step a.
i=1
while i <= 10
do
afficher i
i= i+1
end
Ans:
Code:
val _ =
let
val i = ref 1
in
while !i <= 10 do
i := !i + 1)
end
Output:
Task 2:
1. factor:
Code:
fun factor(x: int, y: int): bool =
if y mod x = 0 then true
else false
2. prime:
Code:
fun prime(x: int): bool =
if x <= 1 then false
else
let
fun isDivisible(n: int, divisor: int): bool =
n mod divisor = 0
in
let
val maxDivisor = Real.floor (Math.sqrt (real x))
fun checkDivisors(d: int): bool =
if d > maxDivisor then true
else if isDivisible(x, d) then false
else checkDivisors(d + 1)
in
checkDivisors(2)
end
end
3. gcd:
Code:
fun gcd(x: int, y: int): int =
if y = 0 then x
else gcd(y, x mod y)
4. perfect:
Code:
fun perfect(x: int): bool =
let
fun sumDivisors(n: int, divisor: int): int =
if divisor >= n then 0
else if n mod divisor = 0 then divisor + sumDivisors(n, divisor + 1)
else sumDivisors(n, divisor + 1)
in
x > 1 andalso (sumDivisors(x, 1) = x)
end
5. amicable:
Code:
fun sumDivisors(n: int): int =
let
fun helper(divisor: int, sum: int): int =
if divisor >= n then sum
else if n mod divisor = 0 then helper(divisor + 1, sum + divisor)
else helper(divisor + 1, sum)
in
helper(1, 0)
end
6. occr:
Code:
fun occr(nums: int list, x: int): int =
let
fun count([], n: int): int = n
| count(h::t, n: int): int =
if h = x then count(t, n + 1)
else count(t, n)
in
count(nums, 0)
end
7. primes:
Code:
fun isPrime(n: int): bool =
if n <= 1 then false
else
let
fun checkDivisors(d: int): bool =
if d * d > n then true
else if n mod d = 0 then false
else checkDivisors(d + 1)
in
checkDivisors(2)
end
8. primeFactors:
Code:
fun prime_factors (n: int): int list =
let
fun is_prime (x: int): bool =
if x < 2 then false
else let
fun check_divisor (d: int): bool =
if d * d > x then true
else if x mod d = 0 then false
else check_divisor (d + 1)
in
check_divisor 2
end
9. merge:
Code:
fun merge([], ys) = ys
| merge(xs, []) = xs
| merge(x::xs, y::ys) =
if x < y then x :: merge(xs, y::ys)
else y :: merge(x::xs, ys)
val l1 = [2,3,5,6]
val l2 = [1,2,4,7,8]
val res = merge(l1, l2)
Output:
10. reverse:
Code:
fun reverse []: int list = []
| reverse [x] = [x]
| reverse (x::xs) = (reverse xs) @ [x]
11. pi:
Code:
fun pi(a, b, f) =
let
fun sum_helper(n, sum) =
if n > b then sum
else sum_helper(n + 1, sum + f(n))
in
sum_helper(a, 0)
end
12. digits:
Code:
fun digits(n) =
let
fun digit_helper(0, res) = res
| digit_helper(n, res) = digit_helper(n div 10,
(n mod 10)::res)
in
if n = 0 then [0] else digit_helper(n, [])
end
val n = 123
val res = digits n
Output:
13. additivePersistence:
Code:
fun sum_of_digits(0) = 0
| sum_of_digits(n) = (n mod 10) + sum_of_digits(n div 10)
fun additivePersistence(n) =
let
fun persistence_helper(n, count) =
let
val next = sum_of_digits(n)
in
if next = n then count
else persistence_helper(next, count + 1)
end
in
persistence_helper(n, 0)
end
Output:
14. digitalRoot:
Code:
fun sum_of_digits(0) = 0
| sum_of_digits(n) = (n mod 10) + sum_of_digits(n div 10)
fun digitalRoot(n) =
if n < 10 then n
else digitalRoot(sum_of_digits(n))
Output:
Exercise 23
- 1 for factorial(0)
Code:
fun factorial n =
else if n = 0 then 1
Output: