docs: public final EObject ruleNegation() throws RecognitionException {
          EObject current = null;
  
          Token otherlv_2=null;
          EObject this_Atom_0 = null;
  
          EObject lv_value_3_0 = null;
  
  
  
          	enterRule();
  
          try {
              // InternalXtext.g:1889:2: ( (this_Atom_0= ruleAtom | ( () otherlv_2= '!' ( (lv_value_3_0= ruleNegation ) ) ) ) )
              // InternalXtext.g:1890:2: (this_Atom_0= ruleAtom | ( () otherlv_2= '!' ( (lv_value_3_0= ruleNegation ) ) ) )
              {
              // InternalXtext.g:1890:2: (this_Atom_0= ruleAtom | ( () otherlv_2= '!' ( (lv_value_3_0= ruleNegation ) ) ) )
              int alt46=2;
              int LA46_0 = input.LA(1);
  
              if ( (LA46_0==RULE_ID||LA46_0==15||(LA46_0>=39 && LA46_0<=40)) ) {
                  alt46=1;
              }
              else if ( (LA46_0==41) ) {
                  alt46=2;
              }
              else {
                  NoViableAltException nvae =
                      new NoViableAltException("", 46, 0, input);
  
                  throw nvae;
              }
              switch (alt46) {
                  case 1 :
                      // InternalXtext.g:1891:3: this_Atom_0= ruleAtom
                      {
  
                      			newCompositeNode(grammarAccess.getNegationAccess().getAtomParserRuleCall_0());
                      		
                      pushFollow(FollowSets000.FOLLOW_2);
                      this_Atom_0=ruleAtom();
  
                      state._fsp--;
  
  
                      			current = this_Atom_0;
                      			afterParserOrEnumRuleCall();
                      		
  
                      }
                      break;
                  case 2 :
                      // InternalXtext.g:1900:3: ( () otherlv_2= '!' ( (lv_value_3_0= ruleNegation ) ) )
                      {
                      // InternalXtext.g:1900:3: ( () otherlv_2= '!' ( (lv_value_3_0= ruleNegation ) ) )
                      // InternalXtext.g:1901:4: () otherlv_2= '!' ( (lv_value_3_0= ruleNegation ) )
                      {
                      // InternalXtext.g:1901:4: ()
                      // InternalXtext.g:1902:5: 
                      {
  
                      					current = forceCreateModelElement(
                      						grammarAccess.getNegationAccess().getNegationAction_1_0(),
                      						current);
                      				
  
                      }
  
                      otherlv_2=(Token)match(input,41,FollowSets000.FOLLOW_26); 
  
                      				newLeafNode(otherlv_2, grammarAccess.getNegationAccess().getExclamationMarkKeyword_1_1());
                      			
                      // InternalXtext.g:1912:4: ( (lv_value_3_0= ruleNegation ) )
                      // InternalXtext.g:1913:5: (lv_value_3_0= ruleNegation )
                      {
                      // InternalXtext.g:1913:5: (lv_value_3_0= ruleNegation )
                      // InternalXtext.g:1914:6: lv_value_3_0= ruleNegation
                      {
  
                      						newCompositeNode(grammarAccess.getNegationAccess().getValueNegationParserRuleCall_1_2_0());
                      					
                      pushFollow(FollowSets000.FOLLOW_2);
                      lv_value_3_0=ruleNegation();
  
                      state._fsp--;
  
  
                      						if (current==null) {
                      							current = createModelElementForParent(grammarAccess.getNegationRule());
                      						}
                      						set(
                      							current,
                      							"value",
                      							lv_value_3_0,
                      							"org.eclipse.xtext.Xtext.Negation");
                      						afterParserOrEnumRuleCall();
                      					
  
                      }
  
  
                      }
  
  
                      }
  
  
                      }
                      break;
  
              }
  
  
              }
  
  
              	leaveRule();
  
          }
  
              catch (RecognitionException re) {
                  recover(input,re);
                  appendSkippedTokens();
              }
          finally {
          }
          return current;
      }