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
The logical-AND operator ( && ) has higher precedence than the logical-OR operator ( || ), so q && r is grouped as an operand. Since the logical operators guarantee evaluation of operands from left to right, q && r is evaluated before s-- .
LOWEST PRECEDENCE The compound logical operators, &&, ||, -a, and -o have low precedence.
R follows the order of operations, where precedence follows the BEDMAS order: Brackets( ), Exponents ^, Division / and Multiplication *, Addition + and Subtraction -.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With