Specifications.Assign2
This assignment is due on Thursday 2/6 by 8:00PM. You should put all of your solutions in a file called assign2/lib/assign2.ml
. See the file test/test_assign2.ml
for example behavior of each function.
These problems come from a list of Exercises on OCaml's webpage. We won't grade these (the solutions are given with the problem statements).
val convert : int_or_string list -> int_list_or_string_list list
Implement the function convert
so that convert l
is an int_list_or_string_list list
in which adjacent string
values and int
values are grouped together. Important. Make sure to include the definitions of int_or_string
and int_list_or_string_list
in your solution.
Implement the function recipes_by_ingrs
such that recipes_by_ingrs recs ingrs
is the sublist of recipes from recs
(preserving their order in recs
) whose ingredients are entirely included in ingrs
. Important. Make sure to include the definition of recipe
in your solution.
type memory = (mem_status * int) list
In this problem, you will be building an allocator for a very simple model of (unlimited) memory. In this model, we represent memory as a list of pairs of values, each representing a chunk of memory. The first entry of the pair tells us if the chunk is Free
or Occupied
, and the second tells us how many units of memory the chunk occupies. Furthermore, we require that memory has the following properties:
Free
chunks of memory (there may be adjacent chunks of Occupied
memory)Free
chunk of memory at the end of the list, i.e., either the list is empty or the last element is an Occupied
block.For example, the list:
[Free 3; Occupied 1; Occupied 3; Free 2; Occupied 1]
would represent the layout:
Status: | F | F | F | O | O | O | O | F | F | O | F | F | ...
Position: 0 1 2 3 4 5 6 7 8 9 10 11 12...
Note that positions do not correspond to indices of chunks in the list.
You will be implementing two functions. The function allocate
allocates memory by placing an Occupied
chunk of memory in the leftmost available position. It's possible to allocate a chunk of memory at position i
of size size
if the positions i
, i + 1
, ..., i + size - 1
are Free
. After allocation, these positions become Occupied
. In the above example, it should be possible to allocate a chunk of memory of size 2
at position 0
giving us the list:
[Occupied 2; Free 1; Occupied 1; Occupied 3; Free 2; Occupied 1]
whereas the leftmost place to allocate a chunk of memory of size 5
is at position 10
, giving us the list:
[Free 3; Occupied 1; Occupied 3; Free 2; Occupied 1; Occupied 5]
The second function free
should make an Occupied
block of memory into a Free
block, given its position. In addition it must maintain the invariants described above.
val allocate : int -> memory -> alloc_result
Implement the function allocate
so that allocate size mem
is an alloc_result
according to the following allocation strategy:
size
is not positive, then it is invalid.allocate size mem
should be the same as mem
except with an Occupied
chuck of memory of size size
in the leftmost possible position, together with the position itself.val free : int -> memory -> free_result
Implement the function free
so that free pos mem
is a free_result
such that:
pos
is negative, or is not the beginning of an Occupied
chunk of memory, then the position is invalidpos
in mem
should be converted to a Free
block and the result should be updated to maintain the above invariants (no adjacent Free
chunks, no ending Free
chunks.\{ \texttt{z} : \texttt{int} \} \vdash \texttt{fun x -> fun y -> x y z + y z + z} : \tau
Is there a type \tau
such that the above typing judgment holds in OCaml? If so, determine the type. If not, justify your answer.
\{ \texttt{g} : \texttt{int -> bool} \} \vdash \texttt{let rec f x = g (f (x + 1))} : \tau
Is there a type \tau
such that the above typing judgment holds in OCaml? If so, determine the type. If not, justify your answer.
Suppose you're interested in adding a kind of functional for-loop into an OCaml-like language. You decide on the syntax
<expr> ::= repeat <expr> times <expr> from <expr>
That is, if e_1
, e_2
, and e_3
are well-formed expressions, then so is
\texttt{repeat} \ e_1 \ \texttt{times} \ e_2 \ \texttt{from} \ e_3
The hope is that you can write code like
let fact n =
let loop =
repeat n times
let (i, m) = acc in
(i + 1, m * i)
from
(1, 1)
in let (_, out) = loop in out
or even:
let fact n =
let loop =
repeat n times
{ i = acc.i + 1; out = acc.out * acc.i }
from
{ i = 1; out = 1 }
in loop.out
Intuitively, we need to requires in repeat n times e1 from e2
that n
is an int
and the e1
and e2
have the same type. Furthermore we require that e1
is well-typed a context which includes a variable acc
which is the same type as that of e1
and e2
.
In English, the typing rule for this new construct is as follows: if e_1
is of type int
in the context \Gamma
, and e_2
is of type \tau
in the context \Gamma
with the additional declaration that the variable acc
is of type \tau
, and e_3
is of type \tau
in the context \Gamma
, then \texttt{repeat} \ e_1 \ \texttt{times} \ e_2 \ \texttt{from} \ e_3
is of type \tau
.
Write this typing rule as a formal inference rule.