Bugs Catalog
AT/Statement/Kernel.h
Copyright © 2011, Reusable Software Research Group, The Ohio State University

//  /*-------------------------------------------------------------------*\
//  |   Abstract Template : Statement_Kernel
//  \*-------------------------------------------------------------------*/

#ifndef AT_STATEMENT_KERNEL
#define AT_STATEMENT_KERNEL 1

///------------------------------------------------------------------------
/// Interface -------------------------------------------------------------
///------------------------------------------------------------------------

enumeration Kind
{
    BLOCK,
    IF,
    IF_ELSE,
    WHILE,
    CALL
};

///------------------------------------------------------------------------

enumeration Condition
{
    NEXT_IS_EMPTY,
    NEXT_IS_NOT_EMPTY,
    NEXT_IS_WALL,
    NEXT_IS_NOT_WALL,
    NEXT_IS_FRIEND,
    NEXT_IS_NOT_FRIEND,
    NEXT_IS_ENEMY,
    NEXT_IS_NOT_ENEMY,
    RANDOM,
    TRUE
};

///------------------------------------------------------------------------

abstract_template <
        concrete_instance class Nested_Statement_Type
        /*!
            implements
                abstract_instance Statement_Kernel <
                        Nested_Statement_Type
                    >
        !*/
    >
class Statement_Kernel
{
public:

    /*!
        math definition IS_IDENTIFIER (
                i: string of character
            ): boolean is
	    i = empty_string or
	    (there exists c: character, s: string of character
		 (i = <c> * s and
		  c is in {'a'..'z', 'A'..'Z'} and
		  for all x: character where (x is in elements (s))
		      (x is in {'a'..'z', 'A'..'Z', '0'..'9', '-'})) and
	     i is not in {"PROGRAM", "IS", "INSTRUCTION", "WHILE", "DO",
			  "IF", "THEN", "ELSE", "BEGIN", "END",
			  "next-is-empty", "next-is-not-empty",
			  "next-is-wall", "next-is-not-wall",
			  "next-is-friend", "next-is-not-friend",
			  "next-is-enemy", "next-is-not-enemy",
			  "random", "true"})

        math subtype IDENTIFIER is string of character
            exemplar i
            constraint
                IS_IDENTIFIER (i)

        math definition IS_CONDITION (
                c: integer
            ): boolean is
	    c is in Condition

        math definition IS_STATEMENT_LABEL (
                kind: integer
                test: integer
                instruction: string of character
            ): boolean is
	    (kind = BLOCK and
	     test = TRUE and
	     instruction = empty_string) or
	    ((kind = IF or kind = IF_ELSE or kind = WHILE) and
	     instruction = empty_string) or
	    (kind = CALL and
	     test = TRUE and
	     instruction /= empty_string)

        math subtype STATEMENT_LABEL is (
                kind: Kind
                test: Condition
                instruction: IDENTIFIER
            )
            exemplar n
            constraint
                IS_STATEMENT_LABEL (n.kind, n.test, n.instruction)

        math subtype STATEMENT is tree of STATEMENT_LABEL
            exemplar s
            constraint
                IS_LEGAL_STATEMENT (s)

        math definition IS_LEGAL_STATEMENT (
                t: tree of STATEMENT_LABEL
            ): boolean satisfies
	    there exists label: STATEMENT_LABEL,
			 nested_stmts: string of tree of STATEMENT_LABEL
		(t = compose (label, nested_stmts) and
		 for all x: tree of STATEMENT_LABEL
		 where (x is in elements (nested_stmts))
		     (IS_LEGAL_STATEMENT (x)) and
		 if label.kind = BLOCK
		 then
		     for all x: tree of STATEMENT_LABEL
		     where (x is in elements (nested_stmts))
			 (root (x).kind /= BLOCK)
		 else if label.kind = IF or label.kind = WHILE
		 then
		     |nested_stmts| = 1 and
		     root(first (nested_stmts)).kind = BLOCK
		 else if label.kind = IF_ELSE
		 then
		     |nested_stmts| = 2 and
		     root(first (nested_stmts)).kind = BLOCK and
		     root(last (nested_stmts)).kind = BLOCK
		 else if label.kind = CALL
		 then
		     |nested_stmts| = 0)

        math definition IS_INITIAL_STATEMENT (
                s: STATEMENT
            ): boolean is
            root (s).kind = BLOCK and
            children (s) = empty_string
    !*/

    standard_abstract_operations (Statement_Kernel);
    /*!
        Statement_Kernel is modeled by STATEMENT
        initialization
            ensures IS_INITIAL_STATEMENT (self)
    !*/

    procedure Add_To_Block (
	    preserves Integer pos,
	    consumes Nested_Statement_Type& statement
        ) is_abstract;
    /*!
	requires
	    root (self).kind = BLOCK and
	    root (statement).kind /= BLOCK and
	    0 <= pos and pos <= |children (self)|
	ensures
	    there exists x, y: string of STATEMENT
		(|x| = pos and
		 children (#self) = x * y and
		 self = compose (root (#self), x * <#statement> * y))
    !*/

    procedure Remove_From_Block (
	    preserves Integer pos,
	    produces Nested_Statement_Type& statement
        ) is_abstract;
    /*!
	requires
	    root (self).kind = BLOCK and
	    0 <= pos and pos < |children (self)|
	ensures
	    there exists x, y: string of STATEMENT
		(|x| = pos and
		 children (#self) = x * <statement> * y and
		 self = compose (root (#self), x * y))
    !*/

    function Integer Length_Of_Block () is_abstract;
    /*!
	requires
	    root (self).kind = BLOCK
	ensures
	    Length_Of_Block = |children (self)|
    !*/

    procedure Compose_If (
	    consumes Integer& cond,
	    consumes Nested_Statement_Type& block
        ) is_abstract;
    /*!
	produces self
	requires
	    IS_CONDITION (cond) and
	    root (block).kind = BLOCK
	ensures
	    self = compose ((IF, #cond, empty_string), <#block>)
    !*/

    procedure Decompose_If (
	    produces Integer& cond,
	    produces Nested_Statement_Type& block
        ) is_abstract;
    /*!
	consumes self
	requires
	    root (self).kind = IF
	ensures
	    #self = compose ((IF, cond, empty_string), <block>)
    !*/

    procedure Compose_If_Else (
	    consumes Integer& cond,
	    consumes Nested_Statement_Type& if_block,
	    consumes Nested_Statement_Type& else_block
        ) is_abstract;
    /*!
	produces self
	requires
	    IS_CONDITION (cond) and
	    root (if_block).kind = BLOCK and
	    root (else_block).kind = BLOCK
	ensures
	    self = compose ((IF_ELSE, #cond, empty_string),
			    <#if_block> * <#else_block>)
    !*/

    procedure Decompose_If_Else (
	    produces Integer& cond,
	    produces Nested_Statement_Type& if_block,
	    produces Nested_Statement_Type& else_block
        ) is_abstract;
    /*!
	consumes self
	requires
	    root (self).kind = IF_ELSE
	ensures
	    #self = compose ((IF_ELSE, cond, empty_string),
			     <if_block> * <else_block>)
    !*/

    procedure Compose_While (
	    consumes Integer& cond,
	    consumes Nested_Statement_Type& block
        ) is_abstract;
    /*!
	produces self
	requires
	    IS_CONDITION (cond) and
	    root (block).kind = BLOCK
	ensures
	    self = compose ((WHILE, #cond, empty_string), <#block>)
    !*/

    procedure Decompose_While (
	    produces Integer& cond,
	    produces Nested_Statement_Type& block
        ) is_abstract;
    /*!
	consumes self
	requires
	    root (self).kind = WHILE
	ensures
	    #self = compose ((WHILE, cond, empty_string), <block>)
    !*/

    procedure Compose_Call (
	    consumes Text& inst
        ) is_abstract;
    /*!
	produces self
	requires
	    IS_IDENTIFIER (inst) and inst /= empty_string
	ensures
	    root (self) = (CALL, TRUE, #inst) and
	    children (self) = empty_string
    !*/

    procedure Decompose_Call (
	    produces Text& inst
        ) is_abstract;
    /*!
	consumes self
	requires
	    root (self).kind = CALL
	ensures
	    #self = compose ((CALL, TRUE, inst), empty_string)
    !*/

    function Integer Kind () is_abstract;
    /*!
	ensures
	    Kind = root (self).kind
    !*/

};

#endif // AT_STATEMENT_KERNEL

Last modified: Fri Sep 02 15:34:31 EDT 2011