#' Combine string arguments by a logical infix operator
#'
#' @param A The first string argument
#' @param B The second string argument
#' @param ... strings to be combined.
#' @param oper = "&" or "|" or  "&&" or "||" \cr
#' And uses "&" as the default, Or uses "|" as the default.
#' @param exp a string to be negated by Not.
#'
#' @details
#' \code{And( "a", "b" )} returns \code{"a & b"} \cr
#' \code{Or( "a", "b" )} returns \code{"a | b"} \cr
#' \code{Not( "exp" )} returns \code{"!exp"} \cr
#' \cr
#' \code{And( "a", "b" )} is equivalent to \code{ "a" \%&\% "b" } \cr
#' \code{And( "a", "b", oper="&&" )} is equivalent to \code{"a" \%&&\% "b"} \cr
#' \code{Or( "a", "b" )} is equivalent to \code{ "a" \%|\% "b" } \cr
#' \code{Or( "a", "b", oper="||" )} is equivalent to \code{ "a" \%||\% "b"} \cr
#' \cr
#' Use \code{eval( parse(text=cond) )} to evaluate the expression.
#'
#' @return
#' a string
#'
#' @examples
#' And( "a==b", "(c==d)" )
#' "a==b" %&% "(c==d)"
#' Or( "a==b", "(c==d)" )
#' "a==b" %||% "(c==d)"
#' Or( Not("a"), Not("(b)") )
#' Not( And("a==b", "(c==d)") )
#'
#' @export
#'

And <- function( ..., oper=" & " ){
 return( paste(add_paren( unlist(list(...)), check=1 ), collapse=oper) )
}

#' @rdname And
#' @export
#'
Or <- function( ..., oper=" | " ){
 return( paste(add_paren( unlist(list(...)), check=1 ), collapse=oper) )
}

#' @rdname And
#' @export
#'
Not <- function( exp, oper=" | " ){
 return( paste("!", add_paren( exp, check=1 ), sep="") )
}


#' @rdname And
#' @export
#'

`%&%` <- function( A, B=NULL ){
 # & operator
 # Shin-ichi Mayekawa
 # 20171006

 if( is.character(A) | is.character(B) ){
  if( is.null(B) ) return( And(TRUE,A))
  else return( And(A,B) )
 }
 else{
  if( is.null(B) )  return(  .Primitive("&")(TRUE,A) )
  else return(  .Primitive("&")(A,B) )
 }
} # end of &


#' @rdname And
#' @export
#'

`%|%` <- function( A, B=NULL ){
 # | operator
 # Shin-ichi Mayekawa
 # 20171006

 if( is.character(A) | is.character(B) ){
  if( is.null(B) ) return( Or(TRUE,A))
  else return( Or(A,B) )
 }
 else{
  if( is.null(B) )  return(  .Primitive("|")(FALSE,A) )
  else return(  .Primitive("|")(A,B) )
 }
} # end of |


#' @rdname And
#' @export
#'

`%&&%` <- function( A, B=NULL ){
 # & operator
 # Shin-ichi Mayekawa
 # 20171006

 if( is.character(A) | is.character(B) ){
  if( is.null(B) ) return( And(TRUE,A, oper=" && "))
  else return( And(A,B, oper=" && ") )
 }
 else{
  if( is.null(B) )  return(  .Primitive("&")(TRUE,A) )
  else return(  .Primitive("&")(A,B) )
 }
} # end of &&


#' @rdname And
#' @export
#'

`%||%` <- function( A, B=NULL ){
 # | operator
 # Shin-ichi Mayekawa
 # 20171006

 if( is.character(A) | is.character(B) ){
  if( is.null(B) ) return( Or(TRUE,A, oper=" || "))
  else return( Or(A,B, oper=" || ") )
 }
 else{
  if( is.null(B) )  return(  .Primitive("|")(FALSE,A) )
  else return(  .Primitive("|")(A,B) )
 }
} # end of ||


