7

I'm trying to make an 'implies' operator for logical variables in R to make propositional calculus easier. However it doesn't seem to be playing nice with the negation operator. As the last 4 lines here indicate, I have to wrap negated variables in parentheses to get the implication operator to work correctly.

I suspect that operator precedence is the issue but I'm not sure. And from what I read there isn't a way to change an infix operator's precedence. Is there a way I could redefine implies() so that the parentheses in (!q) %->% (!p) wouldn't be necessary?

> implies <- function(p, q) !p | q
> "%->%" <- implies
> 
> p <- c(TRUE, TRUE, FALSE, FALSE)
> q <- c(TRUE, FALSE, TRUE, FALSE)
> p %->% q
[1]  TRUE FALSE  TRUE  TRUE
> !q %->% !p
[1]  TRUE FALSE FALSE FALSE
> (!q) %->% !p
[1]  TRUE FALSE  TRUE  TRUE
BBrooklyn
  • 350
  • 1
  • 3
  • 15

1 Answers1

2

R doesn't have any way to control the operator precedence. It's described in the help page ?Syntax. Your problem is that negation has lower priority than special operators, so

!q %->% !p

is parsed as

!(q %->% !p)

Probably the best advice is not to try to use R for the project you're working on, since it's not really designed for that kind of thing. However, what you want might be possible: R allows you to see the parse tree from an expression, and tells where parentheses occur:

> getParseData(parse(text="!q %->% !p"))
   line1 col1 line2 col2 id parent   token terminal text
11     1    1     1   10 11      0    expr    FALSE     
1      1    1     1    1  1     11     '!'     TRUE    !
10     1    2     1   10 10     11    expr    FALSE     
2      1    2     1    2  2      4  SYMBOL     TRUE    q
4      1    2     1    2  4     10    expr    FALSE     
3      1    4     1    7  3     10 SPECIAL     TRUE %->%
9      1    9     1   10  9     10    expr    FALSE     
5      1    9     1    9  5      9     '!'     TRUE    !
6      1   10     1   10  6      8  SYMBOL     TRUE    p
8      1   10     1   10  8      9    expr    FALSE     

Conceivably this could allow you to write a function that could modify the expression to give ! higher precedence than %->%.

Alternatively, your function could just do a text substitution to change %->% or ! into a different precedence operator before parsing, and then change it back before evaluation.

user2554330
  • 37,248
  • 4
  • 43
  • 90