5.3. filtering.fmsl

module Filtering;

	import Questions.Question;
	import QuestionManagement.Database;

	export Filter, Tag, TagKey, Characteristic;

	object Tag
		components:	key:TagKey, keyVal:string;
		description:	(*
				  A key value pair.
				*);
	end Tag;

	object TagKey
		components:	key:string and values:string*;
		description:	(*
				  A tag's key and all possible values.
				*);
	end TagKey;

	object Boolean extends FilterItem
		components:	type:integer;
		description:	(*
				  AND, OR, NOT, (, ), XOR
				*);
	end Boolean;

	object Characteristic
		description:	(*
				  Provided for common inheritance.
				*);
	end Characteristic;

	object CharacteristicCriteria extends Criteria
		components:	type:integer, operator:integer, 
				compareTo:integer;
		description:	(*
				  Some condition on a characteristic.
				*);
	end CharactersiticCriteria;

	object TagCriteria extends Criteria
		components: 	key:TagKey, v:string;
		description:	(*
				  A key value pair to match;
				*);
	end TagCriteria;

	object Criteria extends FilterItem
		description:	(*
				  Provided for common inheritance. A 
				  CharacteristicCriteria or a 
				  TagCriteria.
				*);
	end Criteria;

	object FilterItem
		description:	(*
				  Provided for common inheritance.  
				  Criteria or Boolean.
				*);
		
	end FilterItem;

	object Filter
		components: 	items:FilterItem*;
		description:	(*
				  An ordered set of conditions that describe
				  a set of questions to match.
				*);
	end Filter;

	operation NewFilter
		inputs:		;
		outputs:	filter:Filter;
		precondition:	;
		postcondition:	#filter.items = 0;
		description:	(*
				  Creates an empty filter.
				*);
	end NewFilter;

	operation BuildFilter
		inputs:		filter:Filter, item:FilterItem;
		outputs:	filter':Filter;
		precondition:	;
		postcondition:	forall(i:integer | i >= 1 and
				       i <= #filter.items)
				(filter.items[i] = filter'.items[i]) and
				filter'.items[#filter.items + 1] = item and
				#filter'.items = #filter.items + 1;
		description:	(*
				  Adds something to a filter.
				*);
	end BuildFilter;

	operation RemoveFromFilter
		inputs:		i:integer, filter:Filter;
		outputs:	filter':Filter;
		precondition:	i >=1 and i <= #filter.items;
		postcondition:	#filter'.items = #filter.items - 1 and
				forall(j:integer | j >= 1 and j < i)
				(filter.items[j] = filter'.items[j]) and
				forall(j:integer | j >= i and j <= 
				       #filter'.items)
				(filter.items[j + 1] = filter'.items[j]) and
				not(filter.items[i] in filter'.items);
		description:	(*
				  Removes the given item from the given 
				  filter.
				*);
	end RemoveFromFilter;

	operation FilterQuestions
		inputs:		database:Database, filter:Filter;
		outputs:	questions:Question*;
		precondition:	;
		postcondition:	(* all questions in questions meet the 
				   given filter *);
		description:	(*
				  Returns the questions from the given 
				  database that meet the given filter.
				*);
	end FilterQuestions;

end Filtering;

 


Prev: courses.fmsl | Next: question.fmsl | Up: specification | Top: index