-
-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introducing a "Boolean" context #1033
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice addition, but there are some issues that I have commented on that you might want to think about.
15b2636
to
1877d0e
Compare
Thanks @Alex-Jordan and @dpvc for the feedback, I've incorporated most of the recommended changes. By adding a Value::Type(Boolean) to the end of the _check methods in BOP and UOP, all of the types in the tree are reporting 'Boolean' as expected. (Using I'm still struggling with the T/F constants, however. They keep ending up as Reals when I also now think that L#12 should be I've got to break for today's responsibilities -- happy to receive any suggestions before I'm back at it again tomorrow. |
1877d0e
to
cfad030
Compare
Okay, this is coming along... there are some lingering questions left in the code (and I'm still not clear on replacing Parser::Number -- is this the reason 1 and 0 aren't parseable in strings via Compute/Formula?) I've added 1 and 0 as constants to the context -- which may be the 'right' thing to do anyhow. I noted that Constants don't have a Another oddity I encountered is that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have made a number of important improvements, here, but have also started to work too hard in some places and are starting to go in the wring direction. I've made a lot of comments, but do be discouraged. I think you are almost there.
I tried to explain my recommendations, but if anything isn't clear, let me know. I will write some more about the questions you asked (concerning {parser}{Formula}
and {value}{Formula}
, and some of the history about why things are as they are. I'm hoping that will help clarify the how some of this is set up.
macros/contexts/contextBoolean.pl
Outdated
package context::Boolean::BOP::or; | ||
our @ISA = qw(context::Boolean::BOP); | ||
|
||
sub _eval { return $_[1] || $_[2] ? 1 : 0 } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since $_[1]
and $_[2]
will both be MathObjects, if you use them with ||
, you will always get 1
, as they are truthy as object references. So you need
sub _eval { return $_[1]->value || $_[2]->value ? 1 : 0 }
here and in the other _eval
methods below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I figured this one out 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although it is also necessary to ensure that the result is a MathObject here as well, since returning a raw perl value will not allow ops higher in the tree to call ->value
...
So I have
sub _eval { return $_[0]->Package('Boolean')->new($_[1]->value || $_[2]->value ? 1 : 0) }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is probably better to use
sub _eval { return $_[1]->value || $_[2]->value ? $context::Boolean::T : $context::Boolean::F) }
so you don't have to keep creating new objects (the constructors do a lot of argument checking). Otherwise, when you know the arguments are valid, use make
rather than new
, for efficiency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make
s sense to me 🤡
ee6afd0
to
90476d9
Compare
@dpvc Thanks for putting me back on track! Things really were starting to get kludge-y there... Most of what you've proposed makes sense to me, and it feels good that some of your suggestions were things I'd already uncovered myself. I think things are really starting to fall into place as far as my understanding of PG goes. I still have a few things to clear up, and my thanks in advance for your continued patience and detailed feedback!
Again, let me express my gratitude -- not only for your thorough review of my work -- but for having established this framework for us all. 🙏 Updated commit incoming! |
90476d9
to
bf5b4a2
Compare
Looks like you are making real progress. Here are some responses to your questions above.
This is caused by the Line 1846 in 26f77df
which is trying to call the This function probably needs to be rethought. I think what it probably should be doing is taking an actual value from the function and using its
Can you give an explicit example of this? I'm not able to reproduce this, but I probably don't have the same version of For example, with the changes that I have suggested (using constant context::Boolean::Boolean->new(($p->value || $context::Boolean::T->value ? $context::Boolean::T : $context::Boolean::F)) which is what I would expect. If you mean when you use
The class precedences are used to determine how values are promoted when two MathObjects are used in combination (e.g., when added or multiplied). For example, if you have $a = Real(1);
$b = Complex(2,3);
$c = $a + $b; then in the addition, which MathObject's So In the Boolean context, the only class other than Real (i.e., Boolean) would be List (if you added back the
Yes, as I mentioned, overriding sub isNeg {1} as you know that when this function runs, you know the class is
Yes, that is one of the nice outcomes from this.
Yes, that is crucial, and I will write more about it later. The
If
True. "Constant" is potentially a misnomer, as it is possible to have Formula-valued constants. On the other hand, the Constant class should do better about handling its values. First, the
There isn't anything built-in for that. Perhaps someone did something like that in a separate macro package, but there isn't one in the Parser. I'm not sure what your use case is, but I suspect it would have to take into account an operator's commutativity at least, for which we don't have any data (but you could add that), and potentially associativity, if you want |
Well, its true that in Boolean algebra, there are different preferences for how to handle this; in particular some people prefer that EVERY operation be parenthesized, while others prefer to use the order or precedence. For most programming languages, that has "or" lower than "and" lower than "not". I've seen some that put "xor" between "and" and "not". With this, |
Closed in favor of #1035 |
For item 1, I'll push this onto the stack of future issues. For item 2, refer to #1035 code for Item 3, perfect, thank you. I started down the road of looking into what happens with perl addition/multiplication of these Boolean Formulas and did not continue. With this in hand, I'll explore this rabbit-hole. Item 4, I need to identify more than Item 5, okay -- maybe it was another context (or maybe I dreamed it 😆), you're right that there are probably too many things to control for. Bonus I'll add these precedence options to the request for feedback on #1035 |
I know perl and booleans don't mix. That didn't stop me from trying 😂
Most of this is pretty straightforward, adding some new binary ops for 'and' and 'or', and a unary for 'not'. I annexed addition and multiplication to save some effort -- but I could be convinced that this isn't the right move.
However, I didn't want the stringified versions of these operations to remain '+', '*', and '-', which meant pushing more tokens onto the operators. This is necessary in order to handle something like
$f=Formula("p+q");
followed by$g=Formula("-$f");
Formula creation seeds the Formula object with
{test_points}
and{test_values}
for all combos of the variables in the context. This enables the comparison of boolean formulas for equivalence.perlFormula
is also supported.I'm not sure if anything is necessary for
_check
or wanted for_reduce
.Keeping this as a draft for now, let's get some feedback!