// this file contains rules, that are used to test the matching
// algorithm.
// If the matching of a schema variable contains a free variable. The
// schema variable is only allowed to appear in one instantiation area.
// This is tested by using these rules


\sorts {
  testSort;
  nat;
  Obj \extends Object;
}

\predicates {
  p(testSort);
  q(testSort, testSort);
  q1(nat);
  A;  
}

\functions {
  testSort f(testSort);
  testSort c;

  nat zero;
  nat n;
  nat rn;
  nat m1(nat);
  nat p1(nat);
}

\schemaVariables {
  \term Obj o ; 
  \variables Obj vo ;   
  \formula a, b, b0,post;
  \program Statement #p1, #s ; 
  \program Expression #e2, #e ; 
  \term testSort s, r ;
  \term nat t ;
  \variables testSort y, y0 ;
  \variables nat x ;
  \program Variable #slhs1, #slhs2, #b ; 
  \program LoopInit #loopInit ;
  \program Guard #guard ;
  \program ForUpdates #forupdates ;
  \program VariableInitializer #vi ;
  \program Label #lab ;
  \program Type #ty, #t ;
  \program Variable #var, #v0 ;
  \program[list] Statement #stmnt_list, #slist, #slist1 ;
  \program ExecutionContext #ex ;
  \program Label #inner, #outer;
}

\heuristicsDecl {
}

\rules {
  // if the findexp of a rule is a sequent. if, findexp, rwexp and
  //  addseq are one area. Clash only with addrule possible
  if_addrule_clash { 
      \assumes (a ==>) \find (b->b0 ==>) \replacewith(b0 ==>); 
        \replacewith(==> b); \addrules(add_one{ \assumes (a==>) \find (==>a) \closegoal})};

  find_addrule_clash { 
      \find (a) \replacewith(b) \addrules(add_one{ \assumes (a==>) \find (==>a) \closegoal})};

  count_var_occ_in_addrule { 
      \find (b ==>) \addrules(add_two { 
	   \find (a ==>) \addrules(add_one{ \assumes (a==>) \find (==>a) \closegoal})}
      ); \addrules(add_one{ \assumes (a==>) \find (==>a) \closegoal})};

      
  if_find_clash { \assumes (a ==>) \find (a) \replacewith(b)};

  if_add_no_clash { \assumes (a ==>) \find (b) \add (a ==>); \replacewith(b) };

  close_rule { \assumes (a ==>) \find (==> a) \closegoal };

  not_free_conflict { \find (==>\forall y; (b & b0)) \varcond(\notFreeIn(y, b0))
		        \add (==> \forall y; b & b0)};



  // these rules are needed for a greater test

  test_rule_one { \assumes (==> rn=zero ) \find (p1(m1(rn))) \replacewith(rn) };
  test_rule_two { \find (p1(m1(rn))) \replacewith(rn); \replacewith(p1(m1(zero)))};
  test_rule_three {\find (p1(m1(rn))) \replacewith(p1(m1(zero)))};
  test_rule_four { \find (p1(m1(rn))) \replacewith(p1(m1(zero))) 
              \addrules( addrule1{ \find (p1(m1(rn))) \replacewith(rn);\replacewith(zero)},
			addrule2{ \find (rn) \replacewith(zero) }
			) };

  TestMatchTaclet_eliminate_variable_declaration { \find (\<{.. #t #v0; ...}\>post) 
		\replacewith (\<{..  ...}\>post)} ;

  TestMatchTaclet_whileright {
		\find (\<{.. while(#e2) {#p1} ...}\>post)
                \varcond(\newLabel(#inner), \newLabel(#outer))
	        \replacewith (\<{.. #unwind-loop (#inner, #outer, while(#e2) {#p1});  ...}\>post) }; 

  TestMatchTaclet_whileright_labeled {
		\find (\<{.. #lab:{ while(#e2) {boolean #b = #e2;#p1}} ...}\>post)
                \varcond(\newLabel(#inner), \newLabel(#outer))
	        \replacewith (\<{.. #unwind-loop (#inner, #outer,while(#e2) {#p1});  ...}\>post) }; 

  TestMatchTaclet_break_while {
		\find (\<{..  while(#e2) {break; #stmnt_list} ...}\>post)
	        \replacewith (\<{..  ...}\>post) }; 

  TestMatchTaclet_preincrement { \find (\<{.. #slhs1 = ++#slhs2; ...}\>post) 
			     \replacewith (\<{.. #slhs2 = #slhs2+1; #slhs1 = #slhs1; ...}\>post)  };

  TestMatchTaclet_for_right {
		\find (\<{.. for(#loopInit; #guard; #forupdates) {#p1} ...}\>post)
                \varcond(\newLabel(#inner), \newLabel(#outer))
	        \replacewith (\<{.. #unwind-loop (#inner, #outer,for(#loopInit; #guard; #forupdates) {#p1});  ...}\>post) }; 

  TestMatchTaclet_local_variable_rename { \find (\<{.. {#ty #var=0; #p1} ...}\>post) \replacewith (true)};

  TestMatchTaclet_variable_declaration   { \find (\<{.. #t #v0 = #vi; ...}\>post)
              \replacewith (\<{.. #t #v0; #v0 = #vi; ...}\>post)};

  TestMatchTaclet_empty_block      { \find (\<{.. {} ...}\>post)
            \replacewith (\<{..  ...}\>post) };

  TestMatchTaclet_empty_label      { \find (\<{.. #lab:{} ...}\>post)
            \replacewith (\<{..  ...}\>post) };

  TestMatchTaclet_throw_in_block { \find (\<{.. {{throw #e;}} ...}\>post) 
	\replacewith (\<{.. {throw #e;}  ...}\>post) };

  TestMatchTaclet_for_all {
       \find (\forall x; b ==>) \add ({\subst x; t}(b) ==>) 
  };


  TestMatchTaclet_nocontext  { \find (\<{{#slist}}\>post)
            \replacewith (\<{ #slist }\>post) };

  TestMatchTaclet_assign_n {
       \find ({#var := 2} true) 
       \replacewith(true)
  };

  TestMatchTaclet_while0 {
		\find (\<{.. while(#e2) {#p1} ...}\>A)
	        \replacewith (\<{.. #p1 while(#e2) {#p1};  ...}\>A) }; 


  empty_diamond { \find (\<{}\>b) \replacewith(b) };

 TestMatchTaclet_subsort_termSV   { \find (o) \replacewith (o) };

 TestMatchTaclet_subsort_variableSV   { \find (\forall vo; A) \replacewith (\forall vo; A) };

 TestMatchTaclet_elim_double_block { \find (\<{{ #slist }}\>post) \replacewith (\<{ #slist }\>post) };

 TestMatchTaclet_wrap_blocks { \find ( \<{ {#slist} {#slist1} }\> post )
                    \replacewith ( \<{ {{#slist}} {{#slist1}} }\> post ) };

 TestMatchTaclet_wrap_blocks_two_empty_lists { \find ( \<{ {#slist #stmnt_list} {#slist1} }\> post )
                    \replacewith ( \<{ {{#slist}} {{#slist1}} }\> post ) };

 TestMatchTaclet_remove_empty_blocks { \find ( \<{.. {{#slist}} {} ...}\>post ) \replacewith ( \<{.. ...}\>true ) };

 TestMatchTaclet_bug_matching_lists { \find ( \<{.. { int #v0; #slist } {} ...}\> post ) \replacewith ( true ) };

 TestMatchTaclet_methodframe {
		\find (\<{.. method-frame(#ex){return;} ...}\>post)
	               \replacewith (\<{..  ...}\>post)
 };

 TestMatchTaclet_methodframe_value {
		\find (\<{.. method-frame(#v0, #ex){return #e;} ...}\>post)
	               \replacewith (\<{..  ...}\>post)
 };

testInsequentState {
      \schemaVar \term int i;
      \find (i = 0 ==>)
      \inSequentState
      \replacewith (0 = i ==>)
};

testInsequentState_2 {
      \schemaVar \term int i;
      \find (i = 0 ==>)
      \replacewith (0 = i ==>)
};

}

