(**** * * This file illustrates how to specify formally the requirement that a * collection object contains a certain number of elements. It is defined * using the TestTool spec in particular, but is applicable in general to * counting the number of elements in any collection. * *) obj Q has t:Type and a:Answer; (* Simplified question object *) obj Type has tf:TF or mc:MC; (* Simplified question type *) obj Answer; (* Dont care about the answer here *) obj TF; obj MC; obj Test has ql:QL and OtherStuff; (* Simplified test object *) obj OtherStuff; (* Dont care about other stuff *) obj QL has Q*; (* Question list is the collection in * which we want to count the number of * questions of a particular type *) obj Criteria has hmtf:HowManyTF; (* Simplified test const'n criteria *) obj HowManyTF is integer; op BuildTest(QL, c:Criteria)->t:Test post: (* * The question list in the output test should have as many true/false * questions as requested in the input criteria. *) CountTF(t.ql, c.hmtf); end; (* * Aux function CountTF recursively traverses the given question list, counting * the number of TF questions it finds, returning true if exactly the given * number is found, false otherwise. *) function CountTF(ql:QL, hmtf:HowManyTF)->boolean = if (ql = nil) and (hmtf = 0) (* We succeed when list is empty and *) then true (* we expect to find 0 TF questions.*) else (* We fail when list is empty and *) if (ql = nil) and (hmtf != 0) (* we expect to find more TF ques- *) then false (* tions or we have found too many. *) else (* Otherwise, *) if ql[1].t isa tf (* if ql[1] is a TF question *) then CountTF(ql[2:#ql], (* then chk for 1 fewer TF's in the *) hmtf-1) (* rest of the list *) else CountTF(ql[2:#ql], (* else chk for the same number of *) hmtf); (* TFs in the rest of the list *)