How to query using ← / back arrow / asignment / naming / renaming / declaration - relational-algebra

Student(id, name, address, city, birthYear)
Course(code, courseName, lengthWeeks, institution°)
Institution(instNr, instName, instCity)
Takes(id°, code°)
List the ids and names of students who do not take the Databases course.
t1 ← σ courseName=Databases (Course)
t2 ← t1 ⋈ Takes
t3 ← t2 ⋈ Student
t4 ← π id, name (t3)
t5 ← π id, name (Student)
R ← t5 \ t4
I don't understand the logic behind t5. How can you pick id's and names that are already removed from the relation? Could you do it another way with the ¬?

RA (relational algebra) operators return values given input relation values. (As with everyday addition for integers.) They don't change or establish the values associated with names of variables or constants. That's outside an algebra. The only way a name might get associated with a new value is if your ← is defined to be variable assignment rather than constant declaration. You have to tell us that. Either way it's not a relational algebra operator. It is a symbol in a language whose expressions include more than just names denoting relations (terminals) and nested algebra operator calls (non-terminals). We can in a certain sense consider it an operator of that language but it is not an operator of the algebra. And either way your code never associates a second value with the same name.
(Some RAs have operators that input names as well as relation values in order to disambiguate inputs. But using such input names to associate variable/constant names with values on output is not a RA operation.)
(A RA could define its notion of relation as containing a name and a set of tuples, so it could have an algebraic renaming operator that takes a name and a relation and returns a relation with the given name in its name part. But again that would not affect the value associated with any variable/constant name used to identify the input relation.)
Re "do it another way": Usually we assume some RA operators & some way to name relation values, and then there is an obvious set of query expressions: We take an expression that is a name to denote its associated value and we take an expression that is an operator call to denote the value of calling the operator on the values of its argument expressions. (As with everyday integer arithmetic expressions.)
But a particular query language although defined in terms of such expressions might not actually allow you to write any or all such expressions. (Eg relational tuple calculus & domain calculus.) And/or it might define additional expressions in terms of expression rearrangement without explicitly giving a corresponding operator.
(Some presentations of relational algebras confuse RA operators with expressions of a query language inspired by RA. Then there might be query expressions whose results depend on the variable/constant names that appear as arguments, rather than just the values named by the names that appear as arguments. Then there can be query expressions that you might not be able to write via a nesting of operator calls and that might need you to associate a value with a name via assignment/declaration.)

Related

Retrieve internal/canonical representation of terms in Prolog

I am writing a program for which I need terms in their prefix notation.
The point is to being able to parse mathematical expressions to prefix notation, while preserving the correct order of Operations. I then want to save the result in the database for later use (using assert), which includes translating to another language, which uses prefix notation. Prolog Operators do all have a fixed priority which is a feature I want to use, as I will be using all sorts of operators (including clp operators).
As among others I need to include complete mathematical expressions, such as the equality operator. Thus I cannot recursively use the Univ operator (=..), because it won't accept equality operators etc. Or can I somehow use =.. ?
Essentially I want to work with the internal representation of
N is 3*4+5 % just a random example
which would be
is(N,+(*(3,4),5))
Now, I do know that I can use, write_canonical(N is 3*4+5) to get the internal representation as seen above.
So is there a way to somehow get the internal representation as a term or a list, or something.
Would it be possible to bind the output of write_canonical to a variable?
I hope my question is clear enough.
Prolog terms can be despicted as trees. But, when writing a term, the way a term is displayed depends on the defined operators and write options. Consider:
?- (N is 3*4+5) = is(N,+(*(3,4),5)).
true.
?- (N is 3*4+5) = is(Variable, Expression).
N = Variable,
Expression = 3*4+5.
?- 3*4+5 = +(*(3,4),5).
true.
I.e. operators are syntactic sugar. They don't change how terms are represented, only how terms are displayed.

How to SortBy two parameters in OCL?

I need to sort the collection of Persons by two parameters, by Surnames and after by Names. How can I do something like this in OCL?
The sortedBy function sorts elements using a the criteria expressed in its body and a < relationship between each gathered result.
In your case, assuming that you have a surname attribute, the following statement will sort the collection c using the < operator on each surname gathered (so a < on strings):
c->sortedBy(p | p.surname)
An idea could be to compute a unique string using the surname and the name concatenated toghether. Thus, if you have:
George Smith
Garry Smith
George Smath
The comparison would be done between "Smith_George", "Smith_Garry" and "Smath_George" and would be ordered, following the lexicographical order, to:
George Smath (Smath_George)
Garry Smith (Smith_Garry)
George Smith (smith_George)
Finally, the OCL request would be (assuming surname and name as existing attributes):
c->sortedBy(p | p.surname + '_' + p.name)
This little trick does the job, but it is not "exactly" a two parameters comparison for sortedBy.
The OCL sortedBy(lambda) appears to be very different to Java's sort(comparator) apparently requiring a projection of the objects as the metric for sorting. However if the projection is self, you have a different Java functionality. Therefore if you do sortedBy(p | p) the sorting is dependent on the < operation for p.
To facilitate this, the Eclipse OCL prototype of a future OCL introduces an OclComparable type with a compareTo method enabling all relational operations to be realized provided your custom type extends the OclComparable type.
(A similar OclSummable with zero() and sum() operates supports Collection::sum() generically; e.g. String realizes sum as a concatenation.)
Thanks you inspired me. I just raised http://issues.omg.org/browse/OCL25-213 whose text is:
The sortedBy iteration provides an elegant solution to a sort problem in which the sort metric is a projection of the sorted object. Thus sortedBy(p|p.name) or just sortedBy(name) is short and avoids the opportunities for typos from a more conventional exposition involving comparison of two objects. The natural solution may well be an efficient one for large collections with non-trivial metrics.
However the sortedBy solution is unfamiliar and so confusing for newcomers and unsuitable for multi-key sorting for which an artificial compound single key may need to be constructed.
One solution might be to provide a more conventional iterator such as sort(p1, p2 | comparison-expression) allowing a two key sort:
sort(p1, p2 | let diff1 = p1.key1.compareTo(p2.key1) in
if diff1 <> 0 the diff 1 else p1.key2.compareTo(p2.key2) endif)
However this has poor readability and ample opportunities for typos.
Alternatively sortedBy with a Tuple-valued metric might support multiple keys as:
sortedBy(Tuple{first=key1,second=key2})
(The alphabetical order of the Tuple part names determines the priority.)
(Since sortedBy is declaratively clear and compact, inefficient small/trivial implementations can be optimized to their sort() equivalents.)

Name of unsigned literals in clause normal form

The elements of a logical statement in clause normal form, are called literals.
For example, given the clause {a, !b}
The literals are a , !b.
But suppose you want to obtain the set of elements regardless of whether they are negated.
The 'unsigned literals'(?) are a , b.
What would be a better/more standard term than 'unsigned literals'? One could say 'variables' I suppose, but that seems incongruous in a context where they could be constants, or complex terms in their own right.
The best available answer seems to be 'atoms' as in https://en.wikipedia.org/wiki/Atomic_formula - though the objects in question could be complex terms, they are atoms from the perspective of propositional logic.

Untyped set operations in Isabelle

I have the following code in Isabelle:
typedecl type1
typedecl type2
consts
A::"type1 set"
B::"type2 set"
When I want to use union operation with A and B as bellow:
axiomatization where
c0: "A ∩ B = {}"
Since A and B are sets of different types, I get an error of clash of types which makes sense!
I am wondering if there are any counterparts for set operations that they implicitly consider their operands as pure sets (i.e., ignore their types), therefore something like A ∩' B become possible ( ∩' is ∩ operation counterpart in above sense).
PS:
Another workaround is type casting that I wrote this as a separate question here to better organize my questions.
Thanks
Sets in Isabelle/HOL are always typed, i.e., they contain only elements of one type. If you want to have untyped sets, you have to switch to another logic such as Isabelle/ZF.
Similarly, all values in HOL are annotated with their type, and this is fundamental to the logic. Equality, for example, can only be applied to two values of the same type. Hence, there is no notion of equality between values of different types. Consequently, there is no set operation that ignores the type of values, because such an operation would necessarily have to know how to identify values of different types.

Function to detect conflicting mathematical operators in VB6

I've developed a program which generates insurance quotes using different types of coverages based on state criteria. Now I want to add the ability to specify 'rules'. For example we may have 3 types of coverage (we'll call them UM, BI, and PD). Well some states don't allow PD to be greater than BI and other states don't allow UM to exist without BI. So I've added the ability for the user to create these rules so that when the quote is generated the rule will be followed and thus no state regulations will be violated when the program generates the quote.
The Problem
I don't want the user to be able to select conflicting rules. The user can select any of the VB mathematical operators (>, <, >=, <=, =, <>) and set a coverage on either side. They can do this multiple times (but only one at a time) so they might end up with a list of rules like this:
A > B
B > C
C > A
As you can see, the last rule conflicts with the previously set rules. My solution to this was to validate the list each time the user clicks 'Add rule to list'.
Pretend the 3rd list item is not yet in the list but the user has clicked 'add rule' to put it in the list. The validation process first checks to see if both incoming variables have already been used on the same line. If not, it just searches for the left side incoming variable (in this case 'C') in the already created list. if it finds it, it then sets tmp1 equal to the variable across from the match (tmp1 = 'B'). It then does the same for the incoming variable on the right side (in this case 'A'). Then tmp2 is set equal to the variable across from A (tmp2 = 'B'). If tmp1 and tmp2 are equal then the incoming rule is either conflicting OR is irrelevant regardless of the operators used. I'm pretty sure this is solid logic given 3 variables. However, I found that adding any additional variables could easily bypass my validation. There could be upwards of 10 coverage types in any given state so it is important to be able to validate more than just 3.
Is there any uniform way to do a sound validation given any number of variables? Any ideas or thoughts are appreciated. I hope my explanation makes sense.
Thanks
My best bet is some sort of hierarchical tree of rules. When the user adds the first rule (say A > B), the application could create a data structure like this (lowerValues is a Map which the key leads to a list of values):
lowerValues['A'] = ['B']
Now when the user adds the next rule (B > C), the application could check if B is already in a any lowerValues list (in this case, A). If that happens, C is added to lowerValues['A'], and lowerValues['B'] is also created:
lowerValues['A'] = ['B', 'C']
lowerValues['B'] = ['C']
Finally, when the last rule is provided by the user (C > A), the application checks if C is in any lowerValues list. Since it's in B and A, the rule is invalid.
Hope that helps. I don't remember if there's some sort of mapping in VB. I think you should try the Dictionary object.
In order to this idea works out, all the operations must be internally translated to a simple type. So, for example:
A > B
could be translated as
B <= A
Good luck
In general this is a pretty hard problem. What you in fact want to know is if a set of propositional equations over (apparantly) some set of arithmetic is true. To do this you need what amounts to constraint solvers that "know" arithmetic. Not likely to find that in VB6, but you might be able to invoke one as a subprocess.
If the rules are propositional equations only over inequalities (AA", write them only one way).
Second, try solving the propositions for tautology (see for Wang's algorithm which you can likely implment awkwardly in VB6).
If the propositions are not a tautology, now you want build chains of inequalities (e.g, A > B > C) as a graph and look for cycles. The place this fails is when your propositions have disjunctions, e.g., ("A>B or B>Q"); you'll have to generate an inequality chain for each combination of disjunctions, and discard the inconsistent ones. If you discard all of them, the set is inconsistent. Watch out for expressions like "A and B"; by DeMorgans theorem, they're equivalent to "not A or not B", e.g., "A>B and B>Q" is the same as "A<=B or B<=Q". You might want to reduce the conditions to disjunctive normal form to avoid getting suprised.
There are apparantly decision procedures for such inequalities. They're likely hard to implement.

Resources