We have a ternary predicate Procurement(Supplier, Component, Project). Also, we have three binary Predicates as follows:
Supplies_supplies_Component(Supplier, Component)
Component_used_in_Project(Component, Project)
Supplier_involved_in_Project(Supplier, Project).
For a particular set of Supplier=S1, Component = C1 and Project = P1 (more than one options may be correct)
If all three binary predicates are true, the ternary predicate is also true
If the ternary predicate is true, then all the three binary predicates are true
If all three binary predicates are true, the ternary predicate may or may not be true
If the ternary predicate is true, then all the three binary predicates may or may not be true
I came with this question in my syllabus. Can someone please help me with this?
If the ternary predicate is true, then all the three binary predicates are true
If all three binary predicates are true, the ternary predicate may
or may not be true
It should be actually -
If the ternary predicate is true, then all the three binary predicates are true
If all three binary predicates are true, the ternary predicate may or may not be true
because the following predicates if true,
Supplies_supplies_Component(Supplier, Component) -- may not be used in the same project
Component_used_in_Project(Component, Project) -- may not be supplied by the same supplier
Supplier_involved_in_Project(Supplier, Project) -- but the component supplied may not be used in the same project instance
So by this logic, option 1 proves to be not true.
If the ternary predicate is true, then all the three binary predicates are true
If all three binary predicates are true, the ternary predicate may or may not be true
Related
Google sheets issue. I want a formula that will return TRUE or FALSE if two conditions are met. However for one of the conditions there are two possibilities.
IF A2="Pizza OR Banana" AND B2="Food" then return TRUE
How can I go about it? For now I did the following but I am missing one option (banana):
=IF(AND($A2="Pizza"),$B2="Food")
Thank you!
You could use a formula like
=IF(AND(OR(A2="Pizza", A2="Banana"), B2="Food"), TRUE, FALSE)
Edit:
As pointed out by MattKing, you don't need the IF here at all since AND will give you TRUE/FALSE, you can just use:
=AND(OR(A2="Pizza", A2="Banana"), B2="Food")
try:
=((A2="Pizza")+(A2="Banana"))*(B2="Food")
What if I wanted it to not be case sensitive and to work with Food-FOOD-food and other variants?
=AND(REGEXMATCH($A$2,"(?i)^pizza$|^banana$"),REGEXMATCH($B$2,"(?i)food"))
Use REGEXMATCH instead gives you more control on the conditions.
In this example,
the first REGEXMATCH will do non-case-sensitive check on A2 to see if it is a word started with 'p' end with 'a' spell as 'pizza' or started with 'b' end with 'a' spell as 'banana' (if anything is added before or after 'pizza' and 'banana', such as 'ppizzaa', it returns false),
the second REGEXMATCH do non-case-sensitive check on B2 to see if it is any variants which includes 'food' (even something like 'xFooDy' will return true).
Is there any way that I can get the true value of an OR operation? Something like this?
=OR(value1, value2, value3) return value that is true
try:
=OR(value1, value2, value3)=TRUE
example:
=OR(A1=1, A1=2, A1=3)=TRUE
Taking this question's title literally, the value of any true Or function is always True. However that's probably not what OP is seeking but there's a fundamental misunderstanding that an Or function can have values. Specifically, this question makes a nonsensical assumption that an OR function can have value1, value2, value3. An Or function contains evaluations that return true or false -- no third value possible.
To illustrate, what value would be returned from this Or formula?
=Or(Not(Isnumber(A1)),len(A1)<5,left(C1,1)="G")
However, I understand that this is probably specific to some customized situation. The solution is that some other formula, functionality is needed. If you're evaluating a single cell (i.e. if cell A1 has any three values), then Erik Tyler's proposal of just using an if statement is your answer
=ArrayFormula(IF(OR(A1={5,10,15}),A1,))
(a less elegant but simplified formula that returns the same would be: =if(Or(A1=5,A1=10,A1=15),A1,)
For finding some true values in a range, there are all kinds of possibilities. However to get you started, you might consider using a filter function combined with boolean logic of (evaluation1)+(evaluation2).
See below formula will list off cell addresses of all true values in this Filter function.
=FILTER(Address(ROW(A:A),COLUMN(A:A),4),(A:A=3)+(A:A=5)+(A:A="Hello"))
MATCH (c:OBJ {dummy:false})
where [{param} is null or [(c)-[]->(p:PRO {dummy:false}) WHERE p.val ={param} | true ] ]
return c
I have a big query from which there is this simple part. But
[{param} is null or [(c)-[]->(p:PRO {dummy:false}) WHERE p.val = {param} | true] ]
part is always returning true even if p.val ={param} is false. What did I do wrong here? The syntax looks fine for me.
A pattern comprehension will always return a list, even if it is empty.
So, the following will never equate to false or NULL:
[(c)-[]->(p:PRO {dummy:false}) WHERE p.val = {param} | true]
This query (which tests the size of the inner comprehension result) will probably work for you:
MATCH (c:OBJ {dummy:false})
WHERE [$param IS NULL or SIZE([(c)-->(p:PRO {dummy:false}) WHERE p.val = $param | true]) > 0 ]
RETURN c
There's a couple things going on here. Note cybersam's answer, as it relates to the pattern comprehension within.
However, the bigger problem is that the WHERE clause will ultimately be evaluating a list, NOT a boolean!
By using square brackets for the entirety of your WHERE clause, that means you're creating a list, and its contents will be whatever is inside. The stuff inside will evaluate to a boolean, so this means that there are two possibilities for how this will turn out:
WHERE [true]
or
WHERE [false]
and in either of these cases, these are NOT booleans, but single-element lists, where the only element in the list is a boolean!
Using WHERE on a list like this will ALWAYS evaluate to true. No matter what is in the list. No matter how many elements are in the list. No matter if the list is empty. If the list itself exists, it's going to be evaluated as true, and the WHERE clause succeeds.
So to fix all this, do NOT use square brackets as some means to compartmentalize boolean logic. Use parenthesis instead, and only if you really need them:
MATCH (c:OBJ {dummy:false})
WHERE ( {param} is null or (c)-->(:PRO {dummy:false, val:{param}}) )
RETURN c
In the above, the parenthesis in use when using the WHERE clause aren't really needed, but you can use them if you like.
This should also be a better way of expressing the predicate you want. In this case we don't need the pattern comprehension at all. It's enough to say that we either need the {param} parameter to be null, or this pattern (where one of the properties is the {param} parameter) must exist.
If you really do end up needing a pattern comprehension, follow cybersam's advice and make sure you're testing whether the the list resulting from the comprehension is empty or non-empty.
TL;DR I'm wondering what the pros and cons are (or if they are even equivalent) between #> {as_champion, whatever} and using IN ('as_champion', 'whatever') is. Details below:
I'm working with Rails and using Postgres' array column type, but having to use raw sql for my query as the Rails finder methods don't play nicely with it. I found a way that works, but wondering what the preferred method is:
The roles column on the Memberships table is my array column. It was added via rails as so:
add_column :memberships, :roles, :text, array: true
When I examine the table, it shows the type as: text[] (not sure if that is truly how Postgres represents an array column or if that is Rails shenanigans.
To query against it I do something like:
Membership.where("roles #> ?", '{as_champion, whatever}')
From the fine Array Operators manual:
Operator: #>
Description: contains
Example: ARRAY[1,4,3] #> ARRAY[3,1]
Result: t (AKA true)
So #> treats its operand arrays as sets and checks if the right side is a subset of the left side.
IN is a little different and is used with subqueries:
9.22.2. IN
expression IN (subquery)
The right-hand side is a parenthesized subquery, which must return exactly one column. The left-hand expression is evaluated and compared to each row of the subquery result. The result of IN is "true" if any equal subquery row is found. The result is "false" if no equal row is found (including the case where the subquery returns no rows).
or with literal lists:
9.23.1. IN
expression IN (value [, ...])
The right-hand side is a parenthesized list of scalar expressions. The result is "true" if the left-hand expression's result is equal to any of the right-hand expressions. This is a shorthand notation for
expression = value1
OR
expression = value2
OR
...
So a IN b more or less means:
Is the value a equal to any of the values in the list b (which can be a query producing single element rows or a literal list).
Of course, you can say things like:
array[1] in (select some_array from ...)
array[1] in (array[1], array[2,3])
but the arrays in those cases are still treated like single values (that just happen to have some internal structure).
If you want to check if an array contains any of a list of values then #> isn't what you want. Consider this:
array[1,2] #> array[2,4]
4 isn't in array[1,2] so array[2,4] is not a subset of array[1,2].
If you want to check if someone has both roles then:
roles #> array['as_champion', 'whatever']
is the right expression but if you want to check if roles is any of those values then you want the overlaps operator (&&):
roles && array['as_champion', 'whatever']
Note that I'm using the "array constructor" syntax for the arrays everywhere, that's because it is much more convenient for working with a tool (such as ActiveRecord) that knows to expand an array into a comma delimited list when replacing a placeholder but doesn't fully understand SQL arrays.
Given all that, we can say things like:
Membership.where('roles #> array[?]', %w[as_champion whatever])
Membership.where('roles #> array[:roles]', :roles => some_ruby_array_of_strings)
and everything will work as expected. You're still working with little SQL snippets (as ActiveRecord doesn't have a full understanding of SQL arrays or any way of representing the #> operator) but at least you won't have to worry about quoting problems. You could probably go through AREL to manually add #> support but I find that AREL quickly devolves into an incomprehensible and unreadable mess for all but the most trivial uses.
I want to emulate an "&" operator for searching elements in my mongo db.
there are 4 searchable fields name id tags negative_tags
for a match to be true, any of these could match.
For instance if I search a&b, "a" could be matched in any of the 4 fields and "b" as well. However, they need to both be matched
I tried doing the following
Model.or({:name.all => regexps}, {:id.all =>regexps}, {:tags.all => regexps}, {:negative_tags.all => regexps})
regexps is an array of regexp. For the example given it would be
[ /a/i, /b/i ]
However, this does not behave like I want, because you need the matches to all happen on the same property.
My other try was to run separate mongo queries for each regexps and take the intersection of the sets.
Model.or({:name.in => one_regexp}, {:id.in => one_regexp}, {:tags.in => one_regexp}, {:negative_tags.in => one_regexp})
My problem is that I am not sure how to merge the two hashes. Mongoid lazily evaluates the queries and returns a Mongoid::Criteria object.
I'd like to know how I can do an intersection
There are two distinct ways to handle this. Are you trying to have both regular expressions evaluate per field or can a be true for name and b be true for id?
If it is the latter, I would use a gem for this:
gem 'mongoid_search'
If it is the former, I'd simply join the array into a single regex:
one_regexp.collect {|regexp| "(?=.*#{regexp}" }.join
If what you want to do is to apply two RegEx expressions onto each field, simply put both both in nonconsuming patterns and use one regular expression. This is known as positive lookahead assertion (?=) combined with the .* operator that allows the order to be reversed.
/(?=.*a)(?=.*b)/