We define the signature
module type Ring = sig
type t
val zero : t
val one : t
val add : t -> t -> t
val mul : t -> t -> t
val compare : t -> t -> int
val to_string : t -> string
endof an algebraic ring structure, where add and mul are the two binary operations on the set of elements of type t. Values zero and one represent the identity elements with respect to addition and multiplication. The function compare establishes a total order on the elements of the set. The auxiliary function to_string is used to generate a string representation of an element. This signature is available in ring/libRing.ml.
Furthermore, a matrix is given by the signature:
module type Matrix = sig
type elem
type t
val create : int -> int -> t
val identity : int -> t
val from_rows : elem list list -> t
val row_count : t -> int
val col_count : t -> int
val set : int -> int -> elem -> t -> t
val get : int -> int -> t -> elem
val transpose : t -> t
val add : t -> t -> t
val mul : t -> t -> t
val to_string : t -> string
endHere, elem and t represent the types of the elements of the matrix and the matrix itself, respectively. The functions have the following semantics:
-
create n mcreates an empty (all zeroes)$n\times m$ matrix. -
identity ncreates an$n\times n$ identity matrix. -
row_count mandcol_count mreturn the number of rows and columns inm, respectively. -
from_rows lcreates a matrix from the given list of rows (lists of elements). You may assume thatlis non-empty and all lists have the same length. -
set r c v msets the element at rowrand columncin matrixmto valuev. -
get r c mreturns the element at rowrand columncfrom matrixm. -
transpose mreturns the transpose of matrixm. -
add a badds matricesaandbcomponent-wise. -
mul a bcomputes the matrix multiplication ofaandb. -
to_string mproduces a string representation ofm. Columns shall be separated by single whitespaces and rows by a newline character\n.
This signature is available in matrix/libMatrix.ml.
Perform these tasks:
-
IntRing
In the fileintring/libIntRing.ml: Implement a moduleIntRingthat implements theRingsignature for theinttype. [0.5 points] -
FloatRing
In the filefloatring/libFloatRing.ml: Implement a moduleFloatRingthat implements theRingsignature for thefloattype. [0.5 points] -
FiniteRing
In the filefinitering/libFiniteRing.ml: Define a signatureFiniteRingthat extends theRingsignature with a valueelemsthat represents a list of all elements of the ring's finite set. Make sure that everything in theRingsignature is part ofFiniteRing(without copy-pasting them)! [0.5 points] -
BoolRing
In the fileboolring/libBoolRing.ml: Implement a moduleBoolRingthat implements theFiniteRingsignature for thebooltype. The multiplication in a bool ring is conjunction, the addition is the exclusive or. [0.5 points] -
SetRing
In the filesetring/libSetRing.ml: Implement a functorSetRingthat models a ring over the power set of the set in theFiniteRingpassed as the functor's argument.SetRinghas to implement theRingsignature. We use union and intersection asaddandmuloperations. The representation produced byto_stringis$\left\lbrace e_1,\dots,e_n \right\rbrace$ . Forcomparewe use a bit of an unconventional order. First, we order the elements in the set by their own order and then compare the sets lexicographically, e.g.$\emptyset<\left\lbrace 1,2,3 \right\rbrace<\left\lbrace 2 \right\rbrace<\left\lbrace 2,3 \right\rbrace<\left\lbrace 3 \right\rbrace$ . The typetinSetRingshould beD.t list, ifDis the module that is passed to the functor. Make sure that this information abouttis exposed to the outside. [1.5 points] -
DenseMatrix
In the filedensematrix/libDenseMatrix.ml: Implement a functorDenseMatrixthat satisfies theMatrixsignature. The argument of the functor is aRingthat provides everything to implement the matrix operations. TheDenseMatrixis supposed to store all elements in the matrix in a list of rows, which are lists of elements. [3 points] -
SparseMatrix
In the filesparsematrix/libSparseMatrix.ml: Implement a functorSparseMatrixthat satisfies theMatrixsignature. The argument of the functor is aRingthat provides everything to implement the matrix operations. TheSparseMatrixstores only those elements of the matrix that are non-zero. More precisely, the representation of a sparse matrix must have memory usage proportional to the number of non-zero entries in the matrix ($\mathcal{O}(n)$ ). [3.5 points]
Hint: You may assume that all inputs are valid, e.g. no out-of-bounds access. If you wish to handle invalid input, just throw an exception.
Hint: The function implementations need not be particularly efficient or tail-recursive, just keep your implementations simple where possible.
Testing your solutions is more difficult this week as a test cannot compile if any module it depends on is not correctly implemented or a module signature is incorrectly defined. Thus, we have separated each module into its own dune library (one per directory). This way, we can compile and test each library independently. However, since some tasks require implementations of previous tasks, we have introduced dependencies between the libraries. If building any dependency of a library fails, we cannot test that library (and the corresponding task will receive zero points) as building it would fail too. You can consult the dune files or the graph below to see exactly what the dependencies are. If you don't want to submit a solution for some task, check Artemis to make sure that the public tests for the tasks that you do want to submit pass. In particular, look for the *:build tests, which pass only if that library can be tested and tell you why it cannot otherwise.
Write any code you want to share between tasks in common/common.ml.
To not cause issues with the tests, you should not change the provided dune files (the tests on Artemis will ignore your dune files).
Overview of dependencies
Example: If your implementation of libFiniteRing can't compile, then libBoolRing and libSetRing will not be tested and receive zero points.
Example: You can reuse any implementations you write in libMatrix in libDenseMatrix and libSparseMatrix, but don't change the Matrix signature.
Tip: You can generate similar graphs for any dune project by installing dune-deps with opam install dune-deps, then running e.g. dune-deps | dot -Tpng > deps.png