The Forum for Discussion about The Third Manifesto and Related Matters

Please or Register to create posts and topics.

The type of <TCLOSE>

Quote from AntC on July 10, 2021, 8:30 pm
Quote from Erwin on July 10, 2021, 3:04 pm
Quote from AntC on July 7, 2021, 7:27 am

I really can't see the type of TCLOSE as being a set; nor the type of its operand/result. "characterised by how elements of the type are built" seems more to the point.

If you find the idea of a single RELATION type "dumber" than TTM's notion of myriads of relation types, one for each possible heading, and you also want this discussion to make sense, there's no avoiding having to accept that there are also myriads of TCLOSE operators (one for each possible heading).

I can test Ints for equality; I can test Chars for equality; I can test Dates for equality; I can test Floats for equality; ... And that's just the scalars. Does that mean there are myriads of == operators? I can test TUP{ A Int }s for equality; I can test TUP{ A Char }s for equality; I can test TUP{ B Int }s for equality ... Does that mean there are myriads more == operators, one for each possible TUP heading? And myriads more more == operators, one for each REL{ ... } heading?

No: I say there is one == operator, overloaded for each (scalar) type; and structurally overloaded for each parametric type, like TUP{ A t }; and for each poly-attribute (as I said in my O.P.) TUP{ a t }.

That's true for == because there really is a different operator for each. Testing string equality is a different thing from testing float equality. It's overloaded.

Whereas if you say all RELs have the same type (with some hand-waving about generics); you can't then statically reject operands that are ill-typed for <TCLOSE> (except with more hand-waving).

But no. Every TCLOSE executes precisely the same algorithm, so it's generic rather than overloaded. And the compiler can certainly reject incorrect operands when it performs heading inference. Both arguments have to be relations, and they should have the same heading.

Andl - A New Database Language - andl.org
Quote from AntC on July 10, 2021, 8:30 pm.

Why ?  Because an operator is a function, is a relation, is a subset of a cartesian product of domains.

No. That's the set-based approach that doesn't even work for TTM Selectors/constructed types; let alone TUP, RELs.

  Which domains ?  The relation type of the argument to the TCLOSE at hand.  So if H1 and H2 are distinct headings (both 'compatible' with the requirements imposed on them for their corresponding relation types being subjectible to TCLOSE), then REL{H1} and REL{H2} are distinct relation types, and then REL{H1} X REL{H1} and REL{H2} X REL{H2} are distinct cartesian products, and any subsets of the former is therefore necessarily distinct from any subset of the latter too.  So you arguably have TCLOSE{H1} and TCLOSE{H2} which are distinct operators.  Just TCLOSE can refer only to the entire collection/family/... of operators, and as such it does not make sense to try and pretend TCLOSE as such "has a type".

Or ... You take a richer view of what a type is. Because the TTM set-based approach doesn't stretch. Then the type of an eligible operand to <TCLOSE> is REL{ a t, b t }.

Whereas if you say all RELs have the same type (with some hand-waving about generics); you can't then statically reject operands that are ill-typed for <TCLOSE> (except with more hand-waving).

That "set-based approach" works for me (and it includes selectors/constructors at least for the scalar types), and that's enough for me.  But by all means, feel free to publish your ideas/elaboration of your TTM/v2 including your "richer view of what a type is".  Until that is done, I'll keep feeling bound to classify "richer view" and "doesn't stretch" as exactly the same category of hand-waving that you also accuse others of.

Quote from dandl on July 11, 2021, 10:12 am
Quote from AntC on July 10, 2021, 8:30 pm
Quote from Erwin on July 10, 2021, 3:04 pm
Quote from AntC on July 7, 2021, 7:27 am

I really can't see the type of TCLOSE as being a set; nor the type of its operand/result. "characterised by how elements of the type are built" seems more to the point.

If you find the idea of a single RELATION type "dumber" than TTM's notion of myriads of relation types, one for each possible heading, and you also want this discussion to make sense, there's no avoiding having to accept that there are also myriads of TCLOSE operators (one for each possible heading).

I can test Ints for equality; I can test Chars for equality; I can test Dates for equality; I can test Floats for equality; ... And that's just the scalars. Does that mean there are myriads of == operators? I can test TUP{ A Int }s for equality; I can test TUP{ A Char }s for equality; I can test TUP{ B Int }s for equality ... Does that mean there are myriads more == operators, one for each possible TUP heading? And myriads more more == operators, one for each REL{ ... } heading?

No: I say there is one == operator, overloaded for each (scalar) type; and structurally overloaded for each parametric type, like TUP{ A t }; and for each poly-attribute (as I said in my O.P.) TUP{ a t }.

That's true for == because there really is a different operator for each. Testing string equality is a different thing from testing float equality. It's overloaded.

Whereas if you say all RELs have the same type (with some hand-waving about generics); you can't then statically reject operands that are ill-typed for <TCLOSE> (except with more hand-waving).

But no. Every TCLOSE executes precisely the same algorithm, so it's generic rather than overloaded. And the compiler can certainly reject incorrect operands when it performs heading inference. Both arguments have to be relations, and they should have the same heading.

If you abstract away all the differences then after that, whatever remains, must be "precisely the same".  If it's integer equality that's invoked in one algorithm and timestamp equality in another, then those algorithms are ***NOT*** "precisely the same".  They are only the same at some level of abstraction where all the differences that indeed exist are abstracted away.  The difference in equality operator invoked could maybe even account for a major difference in big-O profile between the two algorithms.  So how on earth can you seriously defend the idea that "they must be precisely the same" ?

Quote from Erwin on July 11, 2021, 2:58 pm
Quote from dandl on July 11, 2021, 10:12 am
Quote from AntC on July 10, 2021, 8:30 pm
Quote from Erwin on July 10, 2021, 3:04 pm
Quote from AntC on July 7, 2021, 7:27 am

I really can't see the type of TCLOSE as being a set; nor the type of its operand/result. "characterised by how elements of the type are built" seems more to the point.

If you find the idea of a single RELATION type "dumber" than TTM's notion of myriads of relation types, one for each possible heading, and you also want this discussion to make sense, there's no avoiding having to accept that there are also myriads of TCLOSE operators (one for each possible heading).

I can test Ints for equality; I can test Chars for equality; I can test Dates for equality; I can test Floats for equality; ... And that's just the scalars. Does that mean there are myriads of == operators? I can test TUP{ A Int }s for equality; I can test TUP{ A Char }s for equality; I can test TUP{ B Int }s for equality ... Does that mean there are myriads more == operators, one for each possible TUP heading? And myriads more more == operators, one for each REL{ ... } heading?

No: I say there is one == operator, overloaded for each (scalar) type; and structurally overloaded for each parametric type, like TUP{ A t }; and for each poly-attribute (as I said in my O.P.) TUP{ a t }.

That's true for == because there really is a different operator for each. Testing string equality is a different thing from testing float equality. It's overloaded.

Whereas if you say all RELs have the same type (with some hand-waving about generics); you can't then statically reject operands that are ill-typed for <TCLOSE> (except with more hand-waving).

But no. Every TCLOSE executes precisely the same algorithm, so it's generic rather than overloaded. And the compiler can certainly reject incorrect operands when it performs heading inference. Both arguments have to be relations, and they should have the same heading.

If you abstract away all the differences then after that, whatever remains, must be "precisely the same".  If it's integer equality that's invoked in one algorithm and timestamp equality in another, then those algorithms are ***NOT*** "precisely the same".  They are only the same at some level of abstraction where all the differences that indeed exist are abstracted away.  The difference in equality operator invoked could maybe even account for a major difference in big-O profile between the two algorithms.  So how on earth can you seriously defend the idea that "they must be precisely the same" ?

I have no idea what point you're trying to make, unless you've misunderstood  mine. So I say:

  • equality of values is typically implemented as a different algorithm for each data type, but they can be treated together as overloads.
  • TCLOSE of relation values is typically implemented as a single algorithm with arguments and return value that vary as to type/heading, so it can be treated as a generic.

Do you disagree, and if so why and how?

Andl - A New Database Language - andl.org
Quote from dandl on July 12, 2021, 1:24 am
Quote from Erwin on July 11, 2021, 2:58 pm
Quote from dandl on July 11, 2021, 10:12 am
Quote from AntC on July 10, 2021, 8:30 pm
Quote from Erwin on July 10, 2021, 3:04 pm
Quote from AntC on July 7, 2021, 7:27 am

I really can't see the type of TCLOSE as being a set; nor the type of its operand/result. "characterised by how elements of the type are built" seems more to the point.

If you find the idea of a single RELATION type "dumber" than TTM's notion of myriads of relation types, one for each possible heading, and you also want this discussion to make sense, there's no avoiding having to accept that there are also myriads of TCLOSE operators (one for each possible heading).

I can test Ints for equality; I can test Chars for equality; I can test Dates for equality; I can test Floats for equality; ... And that's just the scalars. Does that mean there are myriads of == operators? I can test TUP{ A Int }s for equality; I can test TUP{ A Char }s for equality; I can test TUP{ B Int }s for equality ... Does that mean there are myriads more == operators, one for each possible TUP heading? And myriads more more == operators, one for each REL{ ... } heading?

No: I say there is one == operator, overloaded for each (scalar) type; and structurally overloaded for each parametric type, like TUP{ A t }; and for each poly-attribute (as I said in my O.P.) TUP{ a t }.

That's true for == because there really is a different operator for each. Testing string equality is a different thing from testing float equality. It's overloaded.

Whereas if you say all RELs have the same type (with some hand-waving about generics); you can't then statically reject operands that are ill-typed for <TCLOSE> (except with more hand-waving).

But no. Every TCLOSE executes precisely the same algorithm, so it's generic rather than overloaded. And the compiler can certainly reject incorrect operands when it performs heading inference. Both arguments have to be relations, and they should have the same heading.

If you abstract away all the differences then after that, whatever remains, must be "precisely the same".  If it's integer equality that's invoked in one algorithm and timestamp equality in another, then those algorithms are ***NOT*** "precisely the same".  They are only the same at some level of abstraction where all the differences that indeed exist are abstracted away.  The difference in equality operator invoked could maybe even account for a major difference in big-O profile between the two algorithms.  So how on earth can you seriously defend the idea that "they must be precisely the same" ?

I have no idea what point you're trying to make,

Me neither. I'm not sure whether Erwin is trying to make a point against what I [@AntC] said or against @dandl. And since we said different things, neither do I know how/whether Erwin's point is intended to count against both.

Neither of us claimed something was "the same"; let alone "precisely" anything. It's Erwin introduced those words. "abstract away" all what "differences"? Then saying "[not] "precisely the same"" -- 'not' in capitals, triple asterisked -- is that Erwin disagreeing with himself?

Operator == is overloaded -- that is, it has different implementations for different scalar types. I don't feel any need to "publish [my] ideas/elaboration" (not specifically my ideas). ad-hoc polymorphism is an industry-standard idea. Parametric polymorphism is another industry-standard idea. With the theory and algorithms for type inference far better worked out than I could manage.

I specifically mentioned == because the implementation of TCLOSE will need to compare tuples/attribute values for equality, to determine whether its algorithm is generating duplicates and/or to determine when it's reached a fixed point. To do that:

  • If I give the type of its operand/result as REL{ a t, b t } -- because nobody else has offered a formalism;
  • the t appearing in the heading exhibits parametric polymorphism -- the part of the 'search' or recursion algorithm doesn't care what is the type of the attributes;
  • the tuple-comparer will need the specific implementation/overloading for whatever scalar type t is.
  • (Or if it's a TVA/RVA, it'll need to unpack that to compare component-wise -- that is, structural typing -- to eventually get down to scalars/with their overloading.)

The part where I think TTM doesn't stretch is the requirement that an eligible operand must have precisely two attributes; and that they have the same attribute type. Does the mechanism in Appendix A for specifying same attribute name-same attribute type-different relation operands (as needed for 'join compatible') stretch to different name-same attribute type within one heading? The example operator definition  for TRANCLO in DTATRM Ch 6/discussion of RM Pre 19 has hard-coded literal attribute names and type RELATION { X P#, Y P# }.

Remember we're using 'named perspective'. If we're trying to specify something generic (by which I mean flexible as to attribute-name and attribute-type), we can't say 'compare first attribute's value to second attribute's'; there's no notion of position. Can we say 'the value in this tuple for the attribute we've parameterised as a compared to the value in that tuple for the attribute we've parameterised as b'?

unless you've misunderstood  mine. So I say:

  • equality of values is typically implemented as a different algorithm for each data type, but they can be treated together as overloads.
  • TCLOSE of relation values is typically implemented as a single algorithm with arguments and return value that vary as to type/heading, so it can be treated as a generic.

Do you disagree, and if so why and how?

 

Quote from AntC on July 12, 2021, 9:42 am
Quote from dandl on July 12, 2021, 1:24 am
Quote from Erwin on July 11, 2021, 2:58 pm
Quote from dandl on July 11, 2021, 10:12 am
Quote from AntC on July 10, 2021, 8:30 pm
Quote from Erwin on July 10, 2021, 3:04 pm
Quote from AntC on July 7, 2021, 7:27 am

I really can't see the type of TCLOSE as being a set; nor the type of its operand/result. "characterised by how elements of the type are built" seems more to the point.

If you find the idea of a single RELATION type "dumber" than TTM's notion of myriads of relation types, one for each possible heading, and you also want this discussion to make sense, there's no avoiding having to accept that there are also myriads of TCLOSE operators (one for each possible heading).

I can test Ints for equality; I can test Chars for equality; I can test Dates for equality; I can test Floats for equality; ... And that's just the scalars. Does that mean there are myriads of == operators? I can test TUP{ A Int }s for equality; I can test TUP{ A Char }s for equality; I can test TUP{ B Int }s for equality ... Does that mean there are myriads more == operators, one for each possible TUP heading? And myriads more more == operators, one for each REL{ ... } heading?

No: I say there is one == operator, overloaded for each (scalar) type; and structurally overloaded for each parametric type, like TUP{ A t }; and for each poly-attribute (as I said in my O.P.) TUP{ a t }.

That's true for == because there really is a different operator for each. Testing string equality is a different thing from testing float equality. It's overloaded.

Whereas if you say all RELs have the same type (with some hand-waving about generics); you can't then statically reject operands that are ill-typed for <TCLOSE> (except with more hand-waving).

But no. Every TCLOSE executes precisely the same algorithm, so it's generic rather than overloaded. And the compiler can certainly reject incorrect operands when it performs heading inference. Both arguments have to be relations, and they should have the same heading.

If you abstract away all the differences then after that, whatever remains, must be "precisely the same".  If it's integer equality that's invoked in one algorithm and timestamp equality in another, then those algorithms are ***NOT*** "precisely the same".  They are only the same at some level of abstraction where all the differences that indeed exist are abstracted away.  The difference in equality operator invoked could maybe even account for a major difference in big-O profile between the two algorithms.  So how on earth can you seriously defend the idea that "they must be precisely the same" ?

I have no idea what point you're trying to make,

Me neither. I'm not sure whether Erwin is trying to make a point against what I [@AntC] said or against @dandl. And since we said different things, neither do I know how/whether Erwin's point is intended to count against both.

Neither of us claimed something was "the same"; let alone "precisely" anything. It's Erwin introduced those words. "abstract away" all what "differences"? Then saying "[not] "precisely the same"" -- 'not' in capitals, triple asterisked -- is that Erwin disagreeing with himself?

Operator == is overloaded -- that is, it has different implementations for different scalar types. I don't feel any need to "publish [my] ideas/elaboration" (not specifically my ideas). ad-hoc polymorphism is an industry-standard idea. Parametric polymorphism is another industry-standard idea. With the theory and algorithms for type inference far better worked out than I could manage.

I specifically mentioned == because the implementation of TCLOSE will need to compare tuples/attribute values for equality, to determine whether its algorithm is generating duplicates and/or to determine when it's reached a fixed point. To do that:

  • If I give the type of its operand/result as REL{ a t, b t } -- because nobody else has offered a formalism;
  • the t appearing in the heading exhibits parametric polymorphism -- the part of the 'search' or recursion algorithm doesn't care what is the type of the attributes;
  • the tuple-comparer will need the specific implementation/overloading for whatever scalar type t is.
  • (Or if it's a TVA/RVA, it'll need to unpack that to compare component-wise -- that is, structural typing -- to eventually get down to scalars/with their overloading.)

Agreed. Except I don't think TVA/RVA have to be unpacked, just tested for equality. If you unpack, then what?

The part where I think TTM doesn't stretch is the requirement that an eligible operand must have precisely two attributes; and that they have the same attribute type. Does the mechanism in Appendix A for specifying same attribute name-same attribute type-different relation operands (as needed for 'join compatible') stretch to different name-same attribute type within one heading? The example operator definition  for TRANCLO in DTATRM Ch 6/discussion of RM Pre 19 has hard-coded literal attribute names and type RELATION { X P#, Y P# }.

I've provided a formal definition of TCLOSE which I think does that (as D&D might have done it if they hadn't been satisfied with hand-waving).

BTW I have also formalised ETCLOSE, in which additional attributes are computer by defining a dyadic function to get the child value from two parents. Which, as it happens, solves the GTC problem.

Remember we're using 'named perspective'. If we're trying to specify something generic (by which I mean flexible as to attribute-name and attribute-type), we can't say 'compare first attribute's value to second attribute's'; there's no notion of position. Can we say 'the value in this tuple for the attribute we've parameterised as a compared to the value in that tuple for the attribute we've parameterised as b'?

The named perspective demands that you can reliably match up attributes by name, and that you apply RENAME as needed to get that alignment. I don't see a need to 'out-generic' that expectation.

 

Andl - A New Database Language - andl.org
Quote from AntC on July 12, 2021, 9:42 am

 

Neither of us claimed something was "the same"; let alone "precisely" anything. It's Erwin introduced those words.

 

Every TCLOSE executes precisely the same algorithm, so it's generic rather than overloaded.     Dandl on July 11, 2021, 10:12 am.

Whot I'm saying is that {(true,true,true) (false,false,true) (true,false,false) (false,true,false)} and {(2,2,true) (3,3,true) (2,3,false) (3,2,false)} and {(DUM,DUM,true) (DEE,DEE,true) (DUM,DEE,false) (DEE,DUM,false)} are all different relations and if you want to observe that operators are functions are relations (which is exactly what APPXA does, or wants to do, or what it is about), then there is NO WAY to avoid the conclusion that the (in this case) equality operators these relations define/depict/represent/... must be different operators.

Whot I'm also saying is that these conclusions stay exactly the same if you look at {(DUM,DUM,DUM) (DEE,DEE,DEE) (DUM,DEE,DUM) (DEE,DUM,DUM)} (natural join of the nilary relations) and any other relation that defines/denotes/depicts some natural join, e.g. {(DUM,REL{A INT}{},DUM) (DUM,REL{A INT}{TUP{A 1}},DUM) (DEE,REL{A INT}{},DUM) (DEE,REL{A INT}{TUP{A 1}},REL{A INT}{TUP{A 1}}) ...}.

A relatively superficial exercise of deconstruction on "so it's generic rather than overloaded" reveals that apparently there is a logical difference between "generic" and "overloaded".  Might be interesting to know what that is.

Interestingly, "That's true for == because there really is a different operator for each." appears to confirm my original point, except that the follow-up then again wants to insist that despite this difference (which is even confirmed a second time by "Testing string equality is a different thing from testing float equality") we should nonetheless treat these different things as being the same, by stating "It's overloaded.".  The word is not meaningful enough for me to follow the argument.  Not that the intent isn't clear : they're different but we should always deal with it as if they're the same.  I tend to tilt on such nonsense.

Quote from Erwin on July 12, 2021, 9:00 pm
Quote from AntC on July 12, 2021, 9:42 am

 

Neither of us claimed something was "the same"; let alone "precisely" anything. It's Erwin introduced those words.

Is there any substantial issue here? Or are we merely disagreeing how far to stretch "the same" vs "precisely the same" vs "[not] precisely the same", with a side-issue of the capitalisation and asteriskisation for 'not'?

Every TCLOSE executes precisely the same algorithm, so it's generic rather than overloaded.     Dandl on July 11, 2021, 10:12 am.

Neither @dandl nor @Erwin have defined 'generic' here. So all I'm left with is hand-waving. ("generics"/generic programming as a PLT term has too wide a range of uses to be helpful. I notice that wiki's intro para talks about both overloading and parametric types -- which is what I've appealed to. Do you(s) mean something more?)

Every equality test or comparison for Char Strings executes the same algorithm of scanning from left to right. Does that make it generic?

Equality tests in pointer-based languages tend to execute the same algorithm of testing pointers rather than the value, irrespective of the type of the value. Does that make that generic? Or not overloaded? Or Parametric? Or what?

Each TCLOSE implements a different equality test as part of its algorithm, depending on the type of the attribute. Doesn't that make it overloaded?

I've explained it as TCLOSE uses parametric typing in its recursion part and overloading for its attribute value-compare part. Calling some of that 'generic' doesn't add further explanation IMO.

Whot I'm saying is that {(true,true,true) (false,false,true) (true,false,false) (false,true,false)} and {(2,2,true) (3,3,true) (2,3,false) (3,2,false)} and {(DUM,DUM,true) (DEE,DEE,true) (DUM,DEE,false) (DEE,DUM,false)} are all different relations and if you want to observe that operators are functions are relations (which is exactly what APPXA does, or wants to do, or what it is about),

TTM wants us to stop thinking in terms of physreps, and only consider PossReps. Does a D use a different PossRep for equality testing between RELs or TUPs vs between scalars -- and indeed between scalars of different types?

Then it must be quite awkward coding in SIRA_PRISE: before I can write an equality test, I need to think what is the type of the operand, and choose the appropriate operator. And every time I define a new type (RM Pre 1) I must invent a new symbol for equality testing for it.

BTW Appendix A's 'treating operators as relations' only goes so far. Specifically, I think it fails to dispense with RENAME in that way -- exactly because it needs RENAME defined prior, in order to 'apply' a relcon-as-operator to a relation-as-operand. Similarly I rather think the notion of equality is logically prior to 'operators as relations' [**].  I take that bit of Appendix A, to be more tutorial in nature than rigorous.

then there is NO WAY to avoid the conclusion that the (in this case) equality operators these relations define/depict/represent/... must be different operators.

I'm using the maths-defined notion of equality. Notice that wiki uses the same operator for equality between Reals, Peanos, any object within a First-order logic, set elements and sets overall (aha! Relational Theory is sets all the way down).

So I use the symbol and notion for equality appealing to what the wiki calls 'Basic properties', I'd say 'Laws for Equality':

  • Reflexive: x == x, for all x.
  • Symmetric: x == y ≡ y == x. for all x, y
  • Transitive: x == y & y == z ⇒ x == z. for all x, y, z
  • Substitution: x == y ⇒ F(x) == F(y). for all x, y in the domain of F( ). Note this holds even if the co-domain of F( ) is a distinct type vs x, y.
    In a programming context, that law must hold even if F( ) is overloaded for different types, producing a different result type depending on its argument's type.

BTW that Substitution Law is likely to break down with pointer-based languages: calling F(x) in one part of the program will return a different pointer vs calling F(y) in a different part (especially in a different scope). So if you(s) have in mind 'generics' in a pointer-based language, you're probably barking up the wrong tree.

Whot I'm also saying is that these conclusions stay exactly the same if you look at {(DUM,DUM,DUM) (DEE,DEE,DEE) (DUM,DEE,DUM) (DEE,DUM,DUM)} (natural join of the nilary relations) and any other relation that defines/denotes/depicts some natural join, e.g. {(DUM,REL{A INT}{},DUM) (DUM,REL{A INT}{TUP{A 1}},DUM) (DEE,REL{A INT}{},DUM) (DEE,REL{A INT}{TUP{A 1}},REL{A INT}{TUP{A 1}}) ...}.

Ah. "exactly the same". Is that "the same" as "precisely the same"? Or are you using a generics-based notion of "the same"?

A relatively superficial exercise of deconstruction on "so it's generic rather than overloaded" reveals that apparently there is a logical difference between "generic" and "overloaded".  Might be interesting to know what that is.

Yes. I know what "overloaded" means -- see the wiki I linked to. I don't know what "generic" means here. I'm avoiding the term.

@Erwin in message #9 of this thread: If you find the idea of a single RELATION type "dumber" than TTM's notion of myriads of relation types, ...

Re-reading, I see Erwin didn't outright say he does want a single RELATION type. Then what does he want?

Interestingly, "That's true for == because there really is a different operator for each." appears to confirm my original point, except that the follow-up then again wants to insist that despite this difference (which is even confirmed a second time by "Testing string equality is a different thing from testing float equality") we should nonetheless treat these different things as being the same, by stating "It's overloaded.".  The word is not meaningful enough for me to follow the argument.  Not that the intent isn't clear : they're different but we should always deal with it as if they're the same.  I tend to tilt on such nonsense.

OK I'll rephrase: testing String equality has a different implementation vs testing Float equality. Never the less, both test must observe the Equality Laws. In particular if F( ) maps Float to String, we must have x == y ⇒ F(x) == F(y) for all Floats x, y. And that must hold if F( ) is overloaded to map Bool to Int.

Then it must also hold if F( ) is overloaded to map Int to REL{ C Int }.

[Note **]. How do we join a relation-as-operator to a relation-as-operand without a prior notion of equality built over tuples/built over equality-testing of attribute values? That's what I mean by 'logically prior'. Or ... we take joining of relations as logically prior, then == over scalars is a derived operator:

  • x == y =df IS_NOT_EMPTY( REL{ X t }{X x} JOIN REL{ X t }{X y} )

We still have the conundrum: what is t in that heading? Also how to define IS_NOT_EMPTY( ) without sneaking in some notion of equality? We'd have to allow a IS[_NOT]_EMPTY( ) function as an additional primitive in A.

RM Pre 8 is elusive as to which interpretation applies.

Quote from AntC on July 12, 2021, 9:42 am

The part where I think TTM doesn't stretch is the requirement that an eligible operand must have precisely two attributes; and that they have the same attribute type. Does the mechanism in Appendix A for specifying same attribute name-same attribute type-different relation operands (as needed for 'join compatible') stretch to different name-samte type-different relation operands (as needed for 'join compatible') stretch to different name-same attribute type within one heading? The example operator definition  for TRANCLO in DTATRM Ch 6/discussion of RM Pre 19 has hard-coded literal attribute names and type RELATION { X P#, Y P# }.e attribute type within one heading? The example operator definition  for TRANCLO in DTATRM Ch 6/discussion of RM Pre 19 has hard-coded literal attribute names and type RELATION { X P#, Y P# }.

Remember we're using 'named perspective'. If we're trying to specify something generic (by which I mean flexible as to attribute-name and attribute-type), we can't say 'compare first attribute's value to second attribute's'; there's no notion of position. Can we say 'the value in this tuple for the attribute we've parameterised as a compared to the value in that tuple for the attribute we've parameterised as b'?

 

If you're facing a transitive closure scenario where the identifiers are composite (say, a CHAR and an INT) and you get relations of degree > 2 (say, {P1 CHAR, P2 INT, C1 CHAR, C2 INT} that you do want to TCLOSE over, then you can do two things :

  • require the user to first mould this relation into a form that satisfies the "binary" and "same attribute type" requirements, by using WRAPs and RENAMEs to obtain, say, a relation {P TUP{X CHAR, Y INT}, C TUP{X CHAR, Y INT}}.  But that's RENAME (P1->X P2->Y), WRAP (X,Y into P), RENAME again (C1->X C2->Y), WRAP again (X,Y into C).  Tedious.  And if the result of the TCLOSE must be exactly the same type as the input relation for some reason (e.g. because we only want to retain the tuples that are not in the input relation and so we need to do an additional MINUS), then there's yet another two UNWRAPs and RENAMEs to be added in the mix.
  • ditch the "binary" requirement and facilitate the user saying to the system which attributes are to be matched with which

SIRA_PRISE does the latter and the syntax for invoking TCLOSE thus also includes an <attr name matching list> component : TCLOSE ( R , (P1,C1,P2,C2) ).  Telling the system that in the matching process, P1 is to be compared with C1 and P2 with C2, or iow, the equality test to be used is (P1,P2) pairs to (C1,C2) pairs.

Is my understanding correct that this is what your "does not stretch" is about and does this look like a solution ?

I don't know what you're referring to by "the mechanism in Appendix A for specifying ...".  I don't remember any "mechanism".  I'll revisit.

Quote from Erwin on July 14, 2021, 1:07 pm
Quote from AntC on July 12, 2021, 9:42 am

The part where I think TTM doesn't stretch is the requirement that an eligible operand must have precisely two attributes; and that they have the same attribute type. Does the mechanism in Appendix A for specifying same attribute name-same attribute type-different relation operands (as needed for 'join compatible') stretch to different name-samte type-different relation operands (as needed for 'join compatible') stretch to different name-same attribute type within one heading? The example operator definition  for TRANCLO in DTATRM Ch 6/discussion of RM Pre 19 has hard-coded literal attribute names and type RELATION { X P#, Y P# }.e attribute type within one heading? The example operator definition  for TRANCLO in DTATRM Ch 6/discussion of RM Pre 19 has hard-coded literal attribute names and type RELATION { X P#, Y P# }.

Remember we're using 'named perspective'. If we're trying to specify something generic (by which I mean flexible as to attribute-name and attribute-type), we can't say 'compare first attribute's value to second attribute's'; there's no notion of position. Can we say 'the value in this tuple for the attribute we've parameterised as a compared to the value in that tuple for the attribute we've parameterised as b'?

 

If you're facing a transitive closure scenario where the identifiers are composite (say, a CHAR and an INT) and you get relations of degree > 2 (say, {P1 CHAR, P2 INT, C1 CHAR, C2 INT} that you do want to TCLOSE over, then you can do two things :

  • require the user to first mould this relation into a form that satisfies the "binary" and "same attribute type" requirements, by using WRAPs and RENAMEs to obtain, say, a relation {P TUP{X CHAR, Y INT}, C TUP{X CHAR, Y INT}}.  But that's RENAME (P1->X P2->Y), WRAP (X,Y into P), RENAME again (C1->X C2->Y), WRAP again (X,Y into C).  Tedious.  And if the result of the TCLOSE must be exactly the same type as the input relation for some reason (e.g. because we only want to retain the tuples that are not in the input relation and so we need to do an additional MINUS), then there's yet another two UNWRAPs and RENAMEs to be added in the mix.
  • ditch the "binary" requirement and facilitate the user saying to the system which attributes are to be matched with which

SIRA_PRISE does the latter and the syntax for invoking TCLOSE thus also includes an <attr name matching list> component : TCLOSE ( R , (P1,C1,P2,C2) ).  Telling the system that in the matching process, P1 is to be compared with C1 and P2 with C2, or iow, the equality test to be used is (P1,P2) pairs to (C1,C2) pairs.

Is my understanding correct that this is what your "does not stretch" is about

No. I'm talking about TCLOSE over a two-attribute relation, as spec'd in DTATRM.

and does this look like a solution ?

No, because you've given yourself essentially the same problem in a different form: in TCLOSE ( R , (P1,C1,P2,C2) ) you need:

  • the second argument to denote the whole heading of R;
  • P1 to have the same attribute type as C1, P2 as C2.

I don't know what you're referring to by "the mechanism in Appendix A for specifying ...".

See FORMAL DEFINITIONS -- for example, for <AND>.

I don't remember any "mechanism".  I'll revisit.