UQ Students should read the Disclaimer & Warning

Note: This page dates from 2005, and is kept for historical purposes.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>COMP3601 - Assignment 2 - Hire Machine</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
<!--
.wrong {
    background: #FF9999;
}
body {
    background: url(_img/DSC04989.jpg) fixed center;
    font-family: "Arial Unicode MS", Arial, Helvetica, sans-serif;
}
th, td, textarea {
    border: 1px solid #000000;
    padding: 0 1ex;
    background: transparent;
    overflow: hidden;
}
table {
    border: none;
}
-->
</style>
</head>
<body> 
<h1>COMP3601 &ndash; Software Specification &ndash; Assignment Two (Hire Machine) </h1>
<p><a href=".//COMP3601-assignment-2-specification.pdf">Specification</a> (PDF, 123 KB) </p>
<p>I achieved 16 out of a possible 20 marks. </p>
<p><a href=".//COMP3601-assignment-2-Hire.mch.pdf">My Solution</a> (PDF, 42 KB) </p>
<p>Source used to generate the pretty-printed solution above, is shown below. </p>
<p>Hire.mch<br /> 
    <textarea name="b" cols="82" rows="114" readonly="readonly" title="B Code">
/*&quot;


{\bf COMP3601 - Assignment 2}

{\bf Name: Ned Martin}

{\bf Student Number: 40529927}

% Defined for comments
\newcommand{\com}{\vspace{-2.5ex}\em\tiny}
\newcommand{\comb}{\vspace{-2.5ex}\hspace{6ex}\em\tiny}
\newcommand{\ecom}{\normalsize\vspace{-2ex}}

&quot;*/


MACHINE           Hire

SETS ITEMS ; CUSTOMERS

CONSTANTS maxitems, bag_total, total_items, number_of_item, bag_union

PROPERTIES
maxitems : NAT &amp;
bag_total : (ITEMS +-> NAT1) --> NAT1 &amp;
!bb . (bb : (ITEMS +-> NAT1) => bag_total(bb) = SIGMA(zz).(zz : dom(bb) | bb(zz))) &amp;
/*&quot;\com total number of items hired to a customer \ecom&quot;*/
total_items : (((CUSTOMERS * NAT) +-> (ITEMS +-> NAT1)) * CUSTOMERS) --> NAT &amp;
!(hh, cc) . (
  hh : (CUSTOMERS * NAT) +-> (ITEMS +-> NAT1) &amp;
  cc : CUSTOMERS =>
  total_items(hh, cc) =
    SIGMA(zz) . (zz : ({cc} &lt;| dom(hh)) | bag_total(({zz} &lt;| hh)(zz)))
) &amp;

/*&quot;\com total number of specific items on hire \ecom&quot;*/
number_of_item : (((CUSTOMERS * NAT) +-> (ITEMS +-> NAT1)) * ITEMS) --> NAT1 &amp;
!(hh, ii) . (
  hh : (CUSTOMERS * NAT) +-> (ITEMS +-> NAT1) &amp;
  ii : ITEMS
  => number_of_item(hh, ii) = SIGMA(zz) . (zz : dom(hh) | bag_total(hh(zz)))
) &amp;

/*&quot;\com merges two bags \ecom&quot;*/
bag_union : ((ITEMS +-> NAT1) * (ITEMS +-> NAT1)) --> (ITEMS +-> NAT1) &amp;
!(ba, bb) . (
  ba : ITEMS +-> NAT1 &amp;
  bb : ITEMS +-> NAT1
  => bag_union(ba |-> bb) = 
    {xx, yy | xx : (dom(ba) \/ dom(bb)) &amp;
    yy : NAT1 &amp;
    yy = bag_total({xx} &lt;| (ba \/ bb))}
)

VARIABLES
today, stock, hasHired

INVARIANT
today : NAT &amp;
stock : ITEMS +-> NAT &amp;
hasHired : (CUSTOMERS * NAT) +-> (dom(stock) +-> NAT1) &amp;

/*&quot;\com customer cannot hire more than maxitems total \ecom&quot;*/
!cc . (cc : CUSTOMERS => total_items(hasHired, cc) &lt;= maxitems) &amp;
/*&quot;\com cannot hire more items than those in stock \ecom&quot;*/
!ii . (ii : dom(stock) => number_of_item(hasHired, ii) &lt; stock(ii))

INITIALISATION 
today, stock, hasHired := 0, {}, {}


OPERATIONS

/*&quot;Hire given instances of given item to given customer if items are available and customer has not already hired maxitems&quot;*/
hire(item, customer, quantity, duration) =
  PRE
    /*&quot;\comb item is valid stock \ecom&quot;*/
    item: dom(stock) &amp;
    /*&quot;\comb customer is a customer \ecom&quot;*/
    customer: CUSTOMERS &amp;
    /*&quot;\comb quantity is greater than none \ecom&quot;*/
    quantity: NAT1 &amp;
    /*&quot;\comb stock is available, that is, quantity is less than or equal to stock on hand minus stock hired \ecom&quot;*/
    quantity &lt;= (stock(item) - number_of_item(hasHired, item)) &amp;
    /*&quot;\comb customer cannot hire more than maxitems \ecom&quot;*/
    total_items(hasHired, customer) + quantity &lt;= maxitems &amp;
    duration: NAT
  THEN
    /*&quot;\comb add items hired for this customer \ecom&quot;*/
    hasHired(customer |-> (today + duration)) := 
      bag_union(
        ( { (customer |-> (today + duration) ) } &lt;| hasHired )
        ( customer |-> (today + duration) ),
        { (item |-> quantity) }
      )
END;

/*&quot; Output a subset of hasHired which are overdue items where return date is less than today&quot;*/
oi &lt;-- overdue =
  PRE
    /*&quot;\comb nothing to check \ecom&quot;*/
    true
  THEN
    /*&quot;\comb io equals all overdue items \ecom&quot;*/
    oi := (dom(hasHired) |> 1..(today-1)) &lt;| hasHired
END

END
    </textarea>    
    <br />
Portions of code &copy; Copyright 2004 Ned Martin</p>
<p>04-Jun-2004</p> 
</body>
</html>