0% found this document useful (0 votes)
9 views

Lab Assignment4

tdpl

Uploaded by

mednaveen987
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views

Lab Assignment4

tdpl

Uploaded by

mednaveen987
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 27

TDPL ASSIGNMENT – 4

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}

ii. [~2,~1,0,1,2] - ~ unary minus.


Ans: val [_,_,x,_,_] = [~1,~2,0,2,1];

iii. [(3,1), (0,9)]


Ans: val [_, (x,_)] = [(3,1),(0,9)];
Exercise 5
Write a function power of two that tests if an int is a power of 2. Write each step of the
evaluation of (power of two 8).
Code:
fun power_of_two n =
if n=1 then true

else if n mod 2 <> 0 then false


else power_of_two (n div 2)

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

else if x>y then z else y+t;

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.

2. else if x>y then z else y+t:

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.

b. x and y are of same type and hence x is of type int.

3. The type of the function is:

val f = fn : int * int * int * int -> int

Exercise 7
Write 2 functions odd and even that define if an int is even or odd using mutual recursion.

Code:

fun

odd n = if n=0 then false else even (n-1)

and

even n = if n=0 then true else odd (n-1)

fun main() =

let

val a = 6 and b = 7

in

if odd a then print(Int.toString a ^ " is odd\n")

else print(Int.toString a ^ " is even\n");

if odd b then print(Int.toString b ^ " is odd\n")

else print(Int.toString b ^ " is even\n")

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: Error: unbound variable or constructor: x

2. val x = 1; local val x = 2 in val y = x + 1 end; val z = x + 1;

Ans: x = 1, y = 3, z = 2

3. let val x = 1 in let val x = 2 and y = x in x + y end end;

Ans: val it = 3;

Exercise 9
What are the results of the following expressions evaluations.

1. val x = 1 and y = 2 and z = 3;

Ans: x=1, y=2, z=3

2. let val x = x + 1 and z=x+4 in x+z end;

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:

fun insert [] n = [n]

| insert a n =

let

val x::y = a

in

if x<n then [x] @ insert y n

else [n] @ y

end

val res = insert [1,3,4,5,6] 2

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

else if hd l1 < hd l2 then hd l1 :: interclass (tl l1, l2)

else hd l2 :: interclass (l1, tl l2)


val l1 = [2,4,6,8]

val l2 = [1,3,5,6,7]

val res = interclass (l1, l2)

Output:

Exercise 12
Write a function insertion_sort that implements insertion sorting.

Code:
fun insertion_sort l : int list =

if l = [] then []

else let

val (x, rest) = (hd l, tl l)

val sorted_rest = insertion_sort rest

in

insert (x, sorted_rest)

end

and insert (x : int, l : int list) =

if l = [] then [x]

else if x <= hd l then x :: l

else hd l :: insert(x, (tl l))

val l = [2,3,4,1,8,7,5]

val res = insertion_sort l


Output:

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.

3. Write a function bubble that implements the Bubble sort.

Code:

fun iteration (treatment: 'a -> 'a, condition: 'a -> bool, data: 'a) : 'a =

if condition data then data

else iteration (treatment, condition, treatment data)

fun is_sorted [] = true

| is_sorted [x] = true

| is_sorted (x::y::xs) = (x <= y) andalso is_sorted (y::xs)

fun bubble_pass [] = []

| bubble_pass [x] = [x]

| bubble_pass (x::y::xs) =

if x > y then y :: bubble_pass (x::xs)

else x :: bubble_pass (y::xs)

fun bubble lst =

let

val condition = is_sorted

val treatment = bubble_pass


in

iteration (treatment, condition, lst)

end

val l = [4,3,2,1,7,6,4,2]

val res = bubble l

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

val smallerSubsets = subsets xs

in

smallerSubsets @ (List.map (fn subset => x :: subset) smallerSubsets)

end

val mySet = [1, 2, 3]

val mySubsets = subsets mySet

Ouput:
Exercise 15
What is the type of C:

fun C f g x = f (g x);

Ans:

 Let’s denote the type of x as a.

 The function g must take an input of type a, so its type is g : 'a -> 'b for some type b.

 The output of g x will be of type b.

 The function f takes an argument of type b, so its type is f : 'b -> 'c for some type c.

 Hence, the type of C is

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:

F(O,l) = O(a1, O (a2, O(аз, …., O (an-1, On)...)

The list l has 2 or more elements.

Code:

fun f (O, l) =

let

fun process [x,y] = O (x,y)

| process (x::xs) = O (x, process xs)

in

process l

end

val add = fn (x,y) => x + y

val res = f (add, [3,2,1,4])

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:

 The function g takes two parameters:

1. cond: A condition function of type 'a -> bool that checks whether an element should be
included.

2. A list of elements of type 'a.

 g : ('a -> bool) -> 'a list -> 'a list

Code:

fun g (cond, []) = []

| g (cond, x::xs) =

if cond x then x :: g (cond, xs)

else g (cond, xs)

val even = fn a => a mod 2 = 0

val res = g (even, [1,2,3,4,5,6])

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

fun process [x,y] = O (x,y)

| process (x::xs) = O (x, process xs)

in

process l
end

val max = fn (x, y) => if x > y then x else y

val l = [2,3,4,10,33,12]

val res = f (max, l)

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

fun process [x,y] = O (x,y)

| process (x::xs) = O (x, process xs)

in

process l

end

val conc = fn (x, y) => x^y

val l = ["h", "e", "l", "l", "o"]

val res = f (conc, l)

Ouput:
5. Consider the function fold. What is its type?

fun fold F nil y = y | fold F (x::l) y = F(x, (fold F l y));

Ans:

val fold = fn : ('a * 'b -> 'b) -> 'a list -> 'b -> 'b

Exercise 17
Consider the function f:

fun f (x, nil) = nil

| 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.

(1) T_f = ’a -> ’b

(2) ’a = T_x * T_{nil}

(3) ’a = T_x * T_{a::aa}

(4) ’b = T_{nil}

(5) ’b = T_{f(x, aa)}

(6) T_{x(a)} = bool

1. Justify each line of this system of equations.

Ans:

a. x(a) is used in if statement so, it is of type bool

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}.

d. Hence the function f has a type ’a -> ’b;

2. Compute the type of f.

Ans:
val f = fn : ('a -> bool) * 'a list -> 'a list

Exercise 18
Let consider f:

fun f (x,nil) = nil

|f (x,a::aa)= if x(a) then x(a)::f(x,aa) else f (x,aa);

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:

val f = fn : ('a -> bool) * 'a list -> bool list

Exercise 19
1. Write a datatype COORDS that defines the coordinates of a point in 3D.

2. Give examples of the use of COORDS.

Code:

datatype coords = Coords of real * real * real

val point1 = Coords(1.0, 2.0, 3.0)

val point2 = Coords(1.4, 4.2, 2.4)

Output:
3. Using COORDS write a function distance that computes the distance between 2 points.

4. Give an examples of the use of distance.

Code:

datatype coords = Coords of real * real * real

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

val point1 = Coords(2.0, 2.0, 5.0)

val point2 = Coords(1.4, 4.2, 2.4)

val d = distance (point1, point2)

Output:
Exercise 20
Create a datatype PERSON that defines a person defined by its name, frame, age and datebirth.

Ans:

datatype person = Person of {

name : string,

fname : string,

age : int,

dateOfBirth : int * int * int

Exercise 21
1. Create a reference variable i whose value is a reference to 10.

Ans: val i = ref 10;

2. Increment the value of i by 1.

Ans: i := !i + 1;

3. Decrement the value of i by 1.

Ans: i := !i – 1;

4. Change the value of i to 20.

Ans: i := 20;

Exercise 22
while < expression > do < expression> has the following semantics in SML:

a. Evaluate the first expression.

b. If the first expression is false, exit. Else, evaluate the second expression and go

step a.

We want to code the following algorithm in SML:

i=1
while i <= 10

do

afficher i

i= i+1

end

1. Why is the use of references needed?

Ans:

 In Standard ML (SML), which is a functional programming language, immutability is a core


principle.

 Once a value is created, it cannot be changed. We use references to represent mutable


values that can be changed.

2. Write the SML code.

Code:

val _ =

let

val i = ref 1

in

while !i <= 10 do

(print (Int.toString (!i) ^ "\n");

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

val test1 = factor(3, 9)


val test2 = factor(4, 10)
val _ = print (Int.toString (if test1 then 1 else 0) ^ "\n")
val _ = print (Int.toString (if test2 then 1 else 0) ^ "\n")
Output:

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

val test1 = prime(7)


val test2 = prime(10)

val _ = print (Int.toString (if test1 then 1 else 0) ^ "\n")


val _ = print (Int.toString (if test2 then 1 else 0) ^ "\n")
Output:

3. gcd:
Code:
fun gcd(x: int, y: int): int =
if y = 0 then x
else gcd(y, x mod y)

val test1 = gcd(48, 18)


val test2 = gcd(101, 10)
val test3 = gcd(54, 24)

val _ = print (Int.toString test1 ^ "\n")


val _ = print (Int.toString test2 ^ "\n")
val _ = print (Int.toString test3 ^ "\n")
Output:

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

val test1 = perfect(6)


val test2 = perfect(28)
val test3 = perfect(12)

val _ = print (Int.toString (if test1 then 1 else 0) ^ "\n")


val _ = print (Int.toString (if test2 then 1 else 0) ^ "\n")
val _ = print (Int.toString (if test3 then 1 else 0) ^ "\n")
Output:

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

fun amicable(x: int, y: int): bool =


if x <= 1 orelse y <= 1 then false
else
let
val sumX = sumDivisors(x)
val sumY = sumDivisors(y)
in
sumX = y andalso sumY = x
end

val test1 = amicable(220, 284)


val test2 = amicable(10, 12)

val _ = print (Int.toString (if test1 then 1 else 0) ^ "\n")


val _ = print (Int.toString (if test2 then 1 else 0) ^ "\n")

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

val test1 = occr([1, 2, 3, 2, 4, 2], 2)


val test2 = occr([5, 5, 5, 5], 5)

val _ = print (Int.toString test1 ^ "\n")


val _ = print (Int.toString test2 ^ "\n")

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

fun primes(nums: int list): int list =


List.filter isPrime nums

val testList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]


val primeNumbers = primes(testList)

val _ = List.app (fn x => print (Int.toString x ^ "\n")) primeNumbers

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

fun smallest_factor (x: int): int =


if is_prime x then x
else let
fun find_factor (d: int): int =
if d * d > x then x
else if x mod d = 0 then d
else find_factor (d + 1)
in
find_factor 2
end

fun factors (x: int): int list =


if x < 2 then []
else let
val factor = smallest_factor x
in
factor :: factors (x div factor)
end
in
factors n
end

val val1 = prime_factors(10)

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]

val list = [1,2,3,4,5,6]


val res = reverse list
Output:

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

val f = fn x => x*x


val res = pi(1, 5, f)
Output:

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

Write a function factorial that returns:

- 1 for factorial(0)

- generates an exception for a negative parameter and return 0

- n! for a strictly positive parameter

Code:

exception Exception of string

fun factorial n =

if n < 0 then raise Exception ""

else if n = 0 then 1

else n * factorial (n-1)

val res = factorial 5

val res2 = factorial 0

Output:

You might also like