0

I am doing this assignment for homework and I've been stuck on this problem for like 3 hours. I just emailed the professor, but haven't heard back from them yet, so I decided to ask here as well.

We are assigned to write various functions, such as finding the gcd of a fraction in the format (14, 2) where 14 is the numerator and 2 is the denominator.

I have the functions gcd, simplify, add, and times done, but am stuck on addAll.

addAll is supposed to take a list of fractions described as coordinate pairs and sum them all up and simplify it and return the answer as one fraction formated as such (numerator, denominator).

Currently, my addAll function adds them all up and returns the fraction formatted correctly, but it doesn't simplify it. I already have the simplify function written, but whenever I try to call simplify around my addAll recursive call, I get errors.

My current code is this:

fun addAll L = if L = [] then [(0, 1)] else if tl L = nil then L else addAll(    

[
( ((#1 (hd L)) * (#2 (hd (tl L)))) + (#1 (hd (tl L))) * (#2 (hd L)), (#2 (hd L))*(#2 (hd (tl L))) )
]

@

(tl (tl L))

);

(*

a = (#1 (hd L))
b = (#2 (hd L))
c = (#1 (hd (tl L)))
d = (#2 (hd (tl L)))

*)

I was trying to solve the problem by doing this:

fun addAll L = if L = [] then [(0, 1)] else if tl L = nil then L else simplify(addAll(    

[
( ((#1 (hd L)) * (#2 (hd (tl L)))) + (#1 (hd (tl L))) * (#2 (hd L)), (#2 (hd L))*(#2 (hd (tl L))) )
]

@

(tl (tl L))

));

(*

a = (#1 (hd L))
b = (#2 (hd L))
c = (#1 (hd (tl L)))
d = (#2 (hd (tl L)))

*)

but I am getting errors.

Any help would be appreciated.

Thanks.

Also, I will attach my whole code that runs in sml if it helps...

Here is all my code for the assignment:

fun gcd (a, b) =
if b = 0 then a else gcd(b, a mod b);

fun simplify (a, b) = if gcd(a, b) < 2 then (a, b) else ((a div gcd(a, b)), (b div gcd(a, b)));

fun add (a,b) (c,d) = simplify((a*d + c*b), b*d);

fun times (a,b) (c,d) = simplify( (a*c), (b*d) );

fun addAll L = if L = [] then [(0, 1)] else if tl L = nil then L else addAll(    

[
( ((#1 (hd L)) * (#2 (hd (tl L)))) + (#1 (hd (tl L))) * (#2 (hd L)), (#2 (hd L))*(#2 (hd (tl L))) )
]

@

(tl (tl L))

);

(*

a = (#1 (hd L))
b = (#2 (hd L))
c = (#1 (hd (tl L)))
d = (#2 (hd (tl L)))

*)



(*fun timesAll L = if L = [] then [(1, 1)] else if tl L = nil then L else timesAll();*)



fun lessThan (a, b) (c, d) = if ((real a) / (real b)) < ((real c) / (real d)) then true else false;
Josh K
  • 13
  • 2
  • 1
    Please be more specific than "I am getting errors". And you would do yourself a huge favour if you became more familiar with pattern matching. – molbdnilo Sep 25 '20 at 07:18

2 Answers2

0

I FIGURED IT OUT FINALLY!

    fun addAll L = if L = [] then (0, 1) else if tl L = nil then ((#1 (hd L)) , (#2 (hd L))) else simplify(addAll(    

[
( ((#1 (hd L)) * (#2 (hd (tl L)))) + (#1 (hd (tl L))) * (#2 (hd L)), (#2 (hd L))*(#2 (hd (tl L))) )
]

@

(tl (tl L))

));




(*

a = (#1 (hd L))
b = (#2 (hd L))
c = (#1 (hd (tl L)))
d = (#2 (hd (tl L)))

*)
Josh K
  • 13
  • 2
0

Code with a lot of selectors – like hd, tl, #1, ... – is very difficult to read.
Here is your function with pattern matching, which is much easier on the eye:

fun addAll [] = [(0,1)]
  | addAll [x] = [x]
  | addAll ((a0, b0)::(a1, b1)::xs) = addAll ((a0 * b1 + a1 * b0, b0 * b1) :: xs)

(I also replaced the construct [x] @ xs with x :: xs.)

The problem is that this function supposed to produce a pair, not a list of pairs:

fun addAll [] = (0,1)
  | addAll [x] = x
  | addAll ((a0, b0)::(a1, b1)::xs) = addAll ((a0 * b1 + a1 * b0, b0 * b1) :: xs)

and this can be simplifyed.

But: you have already implemented addition, so you don't have to do it again.
In order to add all the elements in a list, you can add its head to the result of adding up all the elements of its tail.
Add a base case and you have

fun addAll [] = (0, 1)
  | addAll (x::xs) =  add x (addAll xs);

(You don't even need this much, but you probably haven't learned about foldl and foldr yet. If you have, try to apply them to this problem.)

You can simplify your timesAll function in the same manner.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82