(**** * * This file defines objects and operation related to adding, editing, and deleting items. * * See Sections 2.5 of the Milestone 4 requirements. * *) module item; from class import Class; export all; object Item is components: children:Item* and parentitem:Item and name:Name and weightandrawscore:WeightAndRawScore and ParentWeightAndRawScore and LatePolicy and DueDate and LatePolicyOptions and collapsed:Collapsed; description: (* An Item is used by an instructor to determine grades for students. An Item is basically a graded item which can contain sub-items which are also Items. *); end Item; object Name is string; object Collapsed is boolean; object WeightAndRawScore is components: weight:Weight and rawscore:RawScore; description: (* This displays information about the current weight and raw score of the item. *); end WeightAndRawScore; object Weight is integer; object RawScore is integer; object ParentWeightAndRawScore is components: ParentWeight and ParentRawScore; description: (* This displays information about the parent weight and raw score of the item. *); end ParentWeightAndRawScore; object ParentWeight is integer; object ParentRawScore is integer; object LatePolicy is components: AllowLatePolicy and OverrideParent; description: (* This displays whether there is a late policy in effect or not. *); end LatePolicy; AllowLatePolicy is boolean; OverrideParent is boolean; object DueDate is components: Month and Day and Year; description: (* This displays the due date of the item. *); end DueDate; object Month is integer; object Day is integer; object Year is integer; object LatePolicyOptions is components: AllowItemLate and AllowGraceDay and DailyDecay and MaxNumberOfUnit and DeductionEachUnitLate; description: (* This displays additional options for the late policy. *); end LatePolicyOptions; object AllowGraceDay is boolean; object AllowItemLate is boolean; object DailyDecay is boolean; object MaxNumberOfUnit is integer; object DeductionEachUnitLate is integer; function SumWeight(l:Item*) = if (#l = 0) then 0 else l[1].weightandrawscore.weight + SumWeight(l[2:#1]); operation AddItem is inputs: class:Class, item:Item; outputs: class':Class; description: (* This operation adds the created item into the class. *); precondition: (* * There are no items in the input class with the same item name as the * item to be added. *) (not (exists (item' in class.it) item'.name = item.name)); postcondition: (* * The given item is in the output class. *) (item in class'.it) and (* * If parentitem is not nil, then the total sum of the weights of items under parentitem must equal 100. *) if (item.parentitem != nil) then (SumWeight(item.parentitem.children) = 100) and (* * An item is in the output class if and only if it is the * new item to be added or it is in the input class. *) forall (item':Item) (item' in class'.it) iff ((item' = item) or (item' in class.it)); end AddItem; operation EditItem is inputs: class:Class, item:Item; outputs: class':Class; description: (* This operation Edits an existing item that is in the class. *); precondition: (* * The given item is in the class *) (item in class.it); postcondition: (* * The given item is in the output class. *) (item in class'.it) and (* * If parentitem is not nil, then the total sum of the weights of items under parentitem must equal 100. *) if (item.parentitem != nil) then (SumWeight(item.parentitem.children) = 100) and (* * An item is in the output class if and only if it is the * item that was edited or it is in the input class. *) forall (item':Item) (item' in class'.it) iff ((item' = item) or (item' in class.it)) and (* * An item in the output class cannot have the same name as another item * in the output class. *) (not (exists (item' in class'.it) item'.name = item.name)); end EditItem; operation DeleteItem is inputs: class:Class, item:Item; outputs: class':Class; description: (* This operation Deletes an existing item that is in the class. *); precondition: (* * The given item is in the class *) (item in class.it); postcondition: (* * An item is in the output class if and only if it is not the * existing item to be deleted and it is in the input class. *) forall (item':Item) (item' in class'.it) iff ((item' != item) and (item' in class.it)); end DeleteItem; end item;