Re: ISSUE-105: Prefixes in SPARQL fragments

On Fri, May 6, 2016 at 4:00 PM, Jim Amsden <jamsden@us.ibm.com> wrote:

> These oslc:prefix and oslc:prefixBase properties are used in parsing OSLC
> Queries. See http://open-services.net/bin/view/Main/OSLCCoreSpecQuery.
> These prefix definitions are defined in a ServiceProvider resource that
> provides the OSLC query capability. These are a convenience to provide a
> set of pre-defined prefixes by the service provider so that query authors
> don't have to specify them in every oslc.prefix query parameter (which is
> not part of the graph pattern) in the query expression.


Although your queries are not SPARQL it looks like a very similar feature
with issue 105.
Could you share more details on this? e.g.
 - is this something the OSLC users use or not
 - how do you deal with multiple defined prefixes
 - other problems that were raised by the WG, e.g. sharing queries with
other services (like copy/paste)
 - how useful is this feature, i.e. would your users live without it?

Thanks,
Dimitris


>
>
>
>
> Jim Amsden, Senior Technical Staff Member
> OSLC and Linked Lifecycle Data
> 919-525-6575
>
>
>
>
> From:        Dimitris Kontokostas <kontokostas@informatik.uni-leipzig.de>
> To:        Miika Alonen <miika.alonen@csc.fi>
> Cc:        public-data-shapes-wg <public-data-shapes-wg@w3.org>
> Date:        05/06/2016 04:26 AM
> Subject:        Re: ISSUE-105: Prefixes in SPARQL fragments
> ------------------------------
>
>
>
> Using Milka's link I noticed that IBM Shapes (OSLC) have a prefix
> declaration mechanism
>
> *http://open-services.net/bin/view/Main/OslcCoreSpecification#Resource_Prefix_Definition*
> <http://open-services.net/bin/view/Main/OslcCoreSpecification#Resource_Prefix_Definition>
>
> Jim, can you tell us what is the use for this since IBM Shapes does not
> use SPARQL ?
>
> On Fri, May 6, 2016 at 10:00 AM, Miika Alonen <*miika.alonen@csc.fi*
> <miika.alonen@csc.fi>> wrote:
> +1 for defining sh:prefix and sh:namespace
>
> Its about time to standardize this:
> *http://lov.okfn.org/dataset/lov/terms?q=prefix*
> <http://lov.okfn.org/dataset/lov/terms?q=prefix>
>
> (wow, never even heard about *https://www.w3.org/ns/rdfa#prefix*
> <https://www.w3.org/ns/rdfa#prefix>)
>
> Its also one of the suggested requirements from RDF Application profiles:
> *http://wiki.dublincore.org/index.php/RDF_Application_Profiles/Requirements#R-220_Define_used_vocabulary*
> <http://wiki.dublincore.org/index.php/RDF_Application_Profiles/Requirements#R-220_Define_used_vocabulary>
>
> The use case for the application profiles is also that there is standard
> way to add descriptions about the used vocabularies. Not all of the used
> vocabularies are resolvable and some are still "hidden" in chargeable
> (ISO/CEN, etc) standards.
>
> I think that the whole point of this is to minimize confusion and make it
> possible to declare preferred prefixes, used namespaces and document the
> intended use of the vocabularies.
>
> Best Regards,
> Miika Alonen
>
> CSC - IT Center for Science
> *miika.alonen@csc.fi* <miika.alonen@csc.fi>
>
> ------------------------------
>
> *From: *"Holger Knublauch" <*holger@topquadrant.com*
> <holger@topquadrant.com>>
> *To: *"public-data-shapes-wg" <*public-data-shapes-wg@w3.org*
> <public-data-shapes-wg@w3.org>>
> *Sent: *Thursday, 5 May, 2016 06:15:14
> *Subject: *Re: ISSUE-105: Prefixes in SPARQL fragments
>
> Just to give further input of why SHACL should include something like
> sh:prefix.
>
> I collected some statistics about stored SPARQL queries in our product.
> These queries are not only constraints, but most of them are part of user
> interface code (SPARQL Web Pages). We have 899 SELECT queries, 240 MODIFY,
> 173 ASK and 43 CONSTRUCT queries. We have 741 SPIN functions, 101 magic
> properties. And we have thousands (!) of small SPARQL snippets (stand-alone
> FILTER/BIND expressions) in IF/LET statements that drive the UI. It would
> be nice to migrate to SHACL syntax in the future, but having to repeat all
> used prefix declarations thousands of times will lead to excessive bloat.
> Note that these statistics only include the standard UI modules in our
> product - we have many more cases (such as SPIN rules and SPARQLMotion
> scripts) in custom consulting projects and customer deployments.
>
> I acknowledge that all points raised by others here (such as difficulty of
> copy and paste, potential confusion with duplicate prefixes and the extra
> overhead of managing sh:prefix triples) are valid. But these points do need
> to be weighed against the cost that also will be there if we don't provide
> anything.
>
> My strong preference remains to support simple ?namespace sh:prefix
> ?prefix triples. This is a predicate that would have been useful to
> standardize a long time ago, for use cases that go beyond SHACL. For
> example it is a perfectly valid scenario that people upload and edit
> resources to a database (that may not manage prefixes) yet want to track
> how these will look like when serialized back to files. It is also a common
> requirement to query the prefix in SPARQL, e.g. to build display strings or
> abbreviations.
>
> In SPIN we did not have this issue because SPIN uses an RDF data model to
> represent queries. This avoids the prefix question because proper
> references to URIs are used, but has the drawbacks that it leads to almost
> unmaintainable Turtle files and that the verbatim syntax as entered by the
> user is lost (e.g. indentation, line breaks formatting and # comments). For
> people who are using SPARQL heavily (such as in TQ's products), these
> aspects are very important.
>
> Holger
>
>
>
> On 24/04/2016 17:41, Eric Prud'hommeaux wrote:
>
> On Apr 24, 2016 7:15 AM, "Holger Knublauch" < <holger@topquadrant.com>
> *holger@topquadrant.com* <holger@topquadrant.com>> wrote:
> >
> > That's an interesting thought, Peter. We could extend and generalize
> this further, basically eliminating the problem of possible prefix
> conflicts: Each sh:sparql triple is already wrapped into an object (such as
> sh:SPARQLValuesDeriver, sh:SPARQLSelectValidator, subclasses of
> sh:SPARQLExecutable) in the current draft. These wrapper objects could all
> have another property sh:prefixes, making it explicit which prefixes are to
> be used:
> >
> > sh:DefaultPrefixes
> >     a sh:PrefixDeclaration ;
> >     sh:prefix [ sh:prefix "rdf" ; sh:namespace *"http://..."* <http:/>]
> ;
> >     sh:prefix [ sh:prefix "owl" ; sh:namespace *"http://..."* <http:/>]
> ;
> >     ...
> >
> > ex:MyPrefixes
> >     a sh:PrefixDeclaration ;
> >     sh:extends sh:DefaultPrefixes ;
> >     sh:prefix [ sh:prefix "ex" ;  sh:namespace "
> <http://example.com/ns#>*http://example.com/ns#* <http://example.com/ns#>"
> ] .
> >
> > and then
> >
> >
> > ex:MyShape
> >     a sh:Shape ;
> >     sh:property [
> >         sh:predicate ex:grandParent ;
> >         sh:derivedValues [
> >             a sh:SPARQLValuesDeriver ;
> >             sh:prefixes ex:MyPrefixes ;
> >
> >             sh:sparql "$this ex:parent/ex:parent ?value" ;
> >         ]
> >     ] .
> >
> > Very chatty syntax, but hopefully closer to acceptable to those who are
> currently against the whole idea.
>
> This doesn't address Mark's comment about cut/pastability but very nicely
> reduces the uncertainty associated with default prefixes.
>
> > Holger
> >
> >
> > On 23/04/2016 22:52, Peter F. Patel-Schneider wrote:
> >>
> >> Another possible approach would be to have a property on these
> constructs that
> >> provided prefixes for the construct only, as in
> >>
> >> ex:MyShape
> >>      a sh:Shape ;
> >>      sh:property [
> >>          sh:predicate ex:grandParent ;
> >>          sh:derivedValues [
> >>              a sh:SPARQLValuesDeriver ;
> >>              sh:prefixHere ( "ex" " <http://example.com/>
> *http://example.com* <http://example.com/>" ) ;
> >>              sh:sparql "$this ex:parent/ex:parent ?value" ;
> >>          ]
> >>      ] .
> >>
> >> On 04/22/2016 04:35 PM, Holger Knublauch wrote:
> >>>
> >>> I just thought about another problem with prefixes. Currently we have
> one
> >>> construct in the spec that operates on SPARQL fragments:
> >>>
> >>> ex:MyShape
> >>>      a sh:Shape ;
> >>>      sh:property [
> >>>          sh:predicate ex:grandParent ;
> >>>          sh:derivedValues [
> >>>              a sh:SPARQLValuesDeriver ;
> >>>              sh:sparql "$this ex:parent/ex:parent ?value" ;
> >>>          ]
> >>>      ] .
> >>>
> >>> Without something like sh:prefix, people would need to always spell
> out the
> >>> full URIs, because they cannot create PREFIX declarations in a SPARQL
> >>> fragment. We already do have other use cases of such fragments in our
> tool
> >>> suite (for expressions that constraint the applicability of menu items
> etc),
> >>> and it is quite plausible that the WG may want to adopt the following
> syntax
> >>> for path-based constraints in the future:
> >>>
> >>> ex:MyShape
> >>>      a sh:Shape ;
> >>>      sh:constraint [
> >>>          a sh:PathConstraint ;
> >>>          sh:path "ex:parent/ex:parent" ;
> >>>          sh:minCount 2 ;
> >>>          sh:maxCount 4 ;
> >>>      ] .
> >>>
> >>> Without sh:prefix we would essentially rule out these syntactic
> choices,
> >>> unless we can get users enthusiastic about always using full URIs.
> >>>
> >>> As always, there are work-arounds, e.g. we could force everything to
> be SELECT
> >>> or ASK queries. But at some stage I find the pain points are really
> becoming
> >>> too big.
> >>>
> >>> Thanks,
> >>> Holger
> >>>
> >>>
> >
> >
>
>
>
> Best Regards,
> Miika Alonen
>
> CSC - IT Center for Science
> *miika.alonen@csc.fi* <miika.alonen@csc.fi>
>
> ------------------------------
>
> *From: *"Holger Knublauch" <*holger@topquadrant.com*
> <holger@topquadrant.com>>
> *To: *"public-data-shapes-wg" <*public-data-shapes-wg@w3.org*
> <public-data-shapes-wg@w3.org>>
> *Sent: *Thursday, 5 May, 2016 06:15:14
> *Subject: *Re: ISSUE-105: Prefixes in SPARQL fragments
>
> Just to give further input of why SHACL should include something like
> sh:prefix.
>
> I collected some statistics about stored SPARQL queries in our product.
> These queries are not only constraints, but most of them are part of user
> interface code (SPARQL Web Pages). We have 899 SELECT queries, 240 MODIFY,
> 173 ASK and 43 CONSTRUCT queries. We have 741 SPIN functions, 101 magic
> properties. And we have thousands (!) of small SPARQL snippets (stand-alone
> FILTER/BIND expressions) in IF/LET statements that drive the UI. It would
> be nice to migrate to SHACL syntax in the future, but having to repeat all
> used prefix declarations thousands of times will lead to excessive bloat.
> Note that these statistics only include the standard UI modules in our
> product - we have many more cases (such as SPIN rules and SPARQLMotion
> scripts) in custom consulting projects and customer deployments.
>
> I acknowledge that all points raised by others here (such as difficulty of
> copy and paste, potential confusion with duplicate prefixes and the extra
> overhead of managing sh:prefix triples) are valid. But these points do need
> to be weighed against the cost that also will be there if we don't provide
> anything.
>
> My strong preference remains to support simple ?namespace sh:prefix
> ?prefix triples. This is a predicate that would have been useful to
> standardize a long time ago, for use cases that go beyond SHACL. For
> example it is a perfectly valid scenario that people upload and edit
> resources to a database (that may not manage prefixes) yet want to track
> how these will look like when serialized back to files. It is also a common
> requirement to query the prefix in SPARQL, e.g. to build display strings or
> abbreviations.
>
> In SPIN we did not have this issue because SPIN uses an RDF data model to
> represent queries. This avoids the prefix question because proper
> references to URIs are used, but has the drawbacks that it leads to almost
> unmaintainable Turtle files and that the verbatim syntax as entered by the
> user is lost (e.g. indentation, line breaks formatting and # comments). For
> people who are using SPARQL heavily (such as in TQ's products), these
> aspects are very important.
>
> Holger
>
>
>
> On 24/04/2016 17:41, Eric Prud'hommeaux wrote:
>
> On Apr 24, 2016 7:15 AM, "Holger Knublauch" < <holger@topquadrant.com>
> *holger@topquadrant.com* <holger@topquadrant.com>> wrote:
> >
> > That's an interesting thought, Peter. We could extend and generalize
> this further, basically eliminating the problem of possible prefix
> conflicts: Each sh:sparql triple is already wrapped into an object (such as
> sh:SPARQLValuesDeriver, sh:SPARQLSelectValidator, subclasses of
> sh:SPARQLExecutable) in the current draft. These wrapper objects could all
> have another property sh:prefixes, making it explicit which prefixes are to
> be used:
> >
> > sh:DefaultPrefixes
> >     a sh:PrefixDeclaration ;
> >     sh:prefix [ sh:prefix "rdf" ; sh:namespace *"http://..."* <http:/>]
> ;
> >     sh:prefix [ sh:prefix "owl" ; sh:namespace *"http://..."* <http:/>]
> ;
> >     ...
> >
> > ex:MyPrefixes
> >     a sh:PrefixDeclaration ;
> >     sh:extends sh:DefaultPrefixes ;
> >     sh:prefix [ sh:prefix "ex" ;  sh:namespace "
> <http://example.com/ns#>*http://example.com/ns#* <http://example.com/ns#>"
> ] .
> >
> > and then
> >
> >
> > ex:MyShape
> >     a sh:Shape ;
> >     sh:property [
> >         sh:predicate ex:grandParent ;
> >         sh:derivedValues [
> >             a sh:SPARQLValuesDeriver ;
> >             sh:prefixes ex:MyPrefixes ;
> >
> >             sh:sparql "$this ex:parent/ex:parent ?value" ;
> >         ]
> >     ] .
> >
> > Very chatty syntax, but hopefully closer to acceptable to those who are
> currently against the whole idea.
>
> This doesn't address Mark's comment about cut/pastability but very nicely
> reduces the uncertainty associated with default prefixes.
>
> > Holger
> >
> >
> > On 23/04/2016 22:52, Peter F. Patel-Schneider wrote:
> >>
> >> Another possible approach would be to have a property on these
> constructs that
> >> provided prefixes for the construct only, as in
> >>
> >> ex:MyShape
> >>      a sh:Shape ;
> >>      sh:property [
> >>          sh:predicate ex:grandParent ;
> >>          sh:derivedValues [
> >>              a sh:SPARQLValuesDeriver ;
> >>              sh:prefixHere ( "ex" " <http://example.com/>
> *http://example.com* <http://example.com/>" ) ;
> >>              sh:sparql "$this ex:parent/ex:parent ?value" ;
> >>          ]
> >>      ] .
> >>
> >> On 04/22/2016 04:35 PM, Holger Knublauch wrote:
> >>>
> >>> I just thought about another problem with prefixes. Currently we have
> one
> >>> construct in the spec that operates on SPARQL fragments:
> >>>
> >>> ex:MyShape
> >>>      a sh:Shape ;
> >>>      sh:property [
> >>>          sh:predicate ex:grandParent ;
> >>>          sh:derivedValues [
> >>>              a sh:SPARQLValuesDeriver ;
> >>>              sh:sparql "$this ex:parent/ex:parent ?value" ;
> >>>          ]
> >>>      ] .
> >>>
> >>> Without something like sh:prefix, people would need to always spell
> out the
> >>> full URIs, because they cannot create PREFIX declarations in a SPARQL
> >>> fragment. We already do have other use cases of such fragments in our
> tool
> >>> suite (for expressions that constraint the applicability of menu items
> etc),
> >>> and it is quite plausible that the WG may want to adopt the following
> syntax
> >>> for path-based constraints in the future:
> >>>
> >>> ex:MyShape
> >>>      a sh:Shape ;
> >>>      sh:constraint [
> >>>          a sh:PathConstraint ;
> >>>          sh:path "ex:parent/ex:parent" ;
> >>>          sh:minCount 2 ;
> >>>          sh:maxCount 4 ;
> >>>      ] .
> >>>
> >>> Without sh:prefix we would essentially rule out these syntactic
> choices,
> >>> unless we can get users enthusiastic about always using full URIs.
> >>>
> >>> As always, there are work-arounds, e.g. we could force everything to
> be SELECT
> >>> or ASK queries. But at some stage I find the pain points are really
> becoming
> >>> too big.
> >>>
> >>> Thanks,
> >>> Holger
> >>>
> >>>
> >
> >
>
>
>
> Best Regards,
> Miika Alonen
>
> CSC - IT Center for Science
> *miika.alonen@csc.fi* <miika.alonen@csc.fi>
>
> ------------------------------
>
> *From: *"Holger Knublauch" <*holger@topquadrant.com*
> <holger@topquadrant.com>>
> *To: *"public-data-shapes-wg" <*public-data-shapes-wg@w3.org*
> <public-data-shapes-wg@w3.org>>
> *Sent: *Thursday, 5 May, 2016 06:15:14
> *Subject: *Re: ISSUE-105: Prefixes in SPARQL fragments
>
> Just to give further input of why SHACL should include something like
> sh:prefix.
>
> I collected some statistics about stored SPARQL queries in our product.
> These queries are not only constraints, but most of them are part of user
> interface code (SPARQL Web Pages). We have 899 SELECT queries, 240 MODIFY,
> 173 ASK and 43 CONSTRUCT queries. We have 741 SPIN functions, 101 magic
> properties. And we have thousands (!) of small SPARQL snippets (stand-alone
> FILTER/BIND expressions) in IF/LET statements that drive the UI. It would
> be nice to migrate to SHACL syntax in the future, but having to repeat all
> used prefix declarations thousands of times will lead to excessive bloat.
> Note that these statistics only include the standard UI modules in our
> product - we have many more cases (such as SPIN rules and SPARQLMotion
> scripts) in custom consulting projects and customer deployments.
>
> I acknowledge that all points raised by others here (such as difficulty of
> copy and paste, potential confusion with duplicate prefixes and the extra
> overhead of managing sh:prefix triples) are valid. But these points do need
> to be weighed against the cost that also will be there if we don't provide
> anything.
>
> My strong preference remains to support simple ?namespace sh:prefix
> ?prefix triples. This is a predicate that would have been useful to
> standardize a long time ago, for use cases that go beyond SHACL. For
> example it is a perfectly valid scenario that people upload and edit
> resources to a database (that may not manage prefixes) yet want to track
> how these will look like when serialized back to files. It is also a common
> requirement to query the prefix in SPARQL, e.g. to build display strings or
> abbreviations.
>
> In SPIN we did not have this issue because SPIN uses an RDF data model to
> represent queries. This avoids the prefix question because proper
> references to URIs are used, but has the drawbacks that it leads to almost
> unmaintainable Turtle files and that the verbatim syntax as entered by the
> user is lost (e.g. indentation, line breaks formatting and # comments). For
> people who are using SPARQL heavily (such as in TQ's products), these
> aspects are very important.
>
> Holger
>
>
>
> On 24/04/2016 17:41, Eric Prud'hommeaux wrote:
>
> On Apr 24, 2016 7:15 AM, "Holger Knublauch" < <holger@topquadrant.com>
> *holger@topquadrant.com* <holger@topquadrant.com>> wrote:
> >
> > That's an interesting thought, Peter. We could extend and generalize
> this further, basically eliminating the problem of possible prefix
> conflicts: Each sh:sparql triple is already wrapped into an object (such as
> sh:SPARQLValuesDeriver, sh:SPARQLSelectValidator, subclasses of
> sh:SPARQLExecutable) in the current draft. These wrapper objects could all
> have another property sh:prefixes, making it explicit which prefixes are to
> be used:
> >
> > sh:DefaultPrefixes
> >     a sh:PrefixDeclaration ;
> >     sh:prefix [ sh:prefix "rdf" ; sh:namespace *"http://..."* <http:/>]
> ;
> >     sh:prefix [ sh:prefix "owl" ; sh:namespace *"http://..."* <http:/>]
> ;
> >     ...
> >
> > ex:MyPrefixes
> >     a sh:PrefixDeclaration ;
> >     sh:extends sh:DefaultPrefixes ;
> >     sh:prefix [ sh:prefix "ex" ;  sh:namespace "
> <http://example.com/ns#>*http://example.com/ns#* <http://example.com/ns#>"
> ] .
> >
> > and then
> >
> >
> > ex:MyShape
> >     a sh:Shape ;
> >     sh:property [
> >         sh:predicate ex:grandParent ;
> >         sh:derivedValues [
> >             a sh:SPARQLValuesDeriver ;
> >             sh:prefixes ex:MyPrefixes ;
> >
> >             sh:sparql "$this ex:parent/ex:parent ?value" ;
> >         ]
> >     ] .
> >
> > Very chatty syntax, but hopefully closer to acceptable to those who are
> currently against the whole idea.
>
> This doesn't address Mark's comment about cut/pastability but very nicely
> reduces the uncertainty associated with default prefixes.
>
> > Holger
> >
> >
> > On 23/04/2016 22:52, Peter F. Patel-Schneider wrote:
> >>
> >> Another possible approach would be to have a property on these
> constructs that
> >> provided prefixes for the construct only, as in
> >>
> >> ex:MyShape
> >>      a sh:Shape ;
> >>      sh:property [
> >>          sh:predicate ex:grandParent ;
> >>          sh:derivedValues [
> >>              a sh:SPARQLValuesDeriver ;
> >>              sh:prefixHere ( "ex" " <http://example.com/>
> *http://example.com* <http://example.com/>" ) ;
> >>              sh:sparql "$this ex:parent/ex:parent ?value" ;
> >>          ]
> >>      ] .
> >>
> >> On 04/22/2016 04:35 PM, Holger Knublauch wrote:
> >>>
> >>> I just thought about another problem with prefixes. Currently we have
> one
> >>> construct in the spec that operates on SPARQL fragments:
> >>>
> >>> ex:MyShape
> >>>      a sh:Shape ;
> >>>      sh:property [
> >>>          sh:predicate ex:grandParent ;
> >>>          sh:derivedValues [
> >>>              a sh:SPARQLValuesDeriver ;
> >>>              sh:sparql "$this ex:parent/ex:parent ?value" ;
> >>>          ]
> >>>      ] .
> >>>
> >>> Without something like sh:prefix, people would need to always spell
> out the
> >>> full URIs, because they cannot create PREFIX declarations in a SPARQL
> >>> fragment. We already do have other use cases of such fragments in our
> tool
> >>> suite (for expressions that constraint the applicability of menu items
> etc),
> >>> and it is quite plausible that the WG may want to adopt the following
> syntax
> >>> for path-based constraints in the future:
> >>>
> >>> ex:MyShape
> >>>      a sh:Shape ;
> >>>      sh:constraint [
> >>>          a sh:PathConstraint ;
> >>>          sh:path "ex:parent/ex:parent" ;
> >>>          sh:minCount 2 ;
> >>>          sh:maxCount 4 ;
> >>>      ] .
> >>>
> >>> Without sh:prefix we would essentially rule out these syntactic
> choices,
> >>> unless we can get users enthusiastic about always using full URIs.
> >>>
> >>> As always, there are work-arounds, e.g. we could force everything to
> be SELECT
> >>> or ASK queries. But at some stage I find the pain points are really
> becoming
> >>> too big.
> >>>
> >>> Thanks,
> >>> Holger
> >>>
> >>>
> >
> >
>
>
>
>
>
> --
> Dimitris Kontokostas
> Department of Computer Science, University of Leipzig & DBpedia Association
> Projects: *http://dbpedia.org* <http://dbpedia.org/>,
> *http://rdfunit.aksw.org* <http://rdfunit.aksw.org/>, http://
> *http://aligned-project.eu* <http://aligned-project.eu/>
> Homepage:*http://aksw.org/DimitrisKontokostas*
> <http://aksw.org/DimitrisKontokostas>
> Research Group: AKSW/KILT *http://aksw.org/Groups/KILT*
> <http://aksw.org/Groups/KILT>
>
>
>
>


-- 
Dimitris Kontokostas
Department of Computer Science, University of Leipzig & DBpedia Association
Projects: http://dbpedia.org, http://rdfunit.aksw.org, http://
http://aligned-project.eu
Homepage:http://aksw.org/DimitrisKontokostas
Research Group: AKSW/KILT http://aksw.org/Groups/KILT

Received on Friday, 6 May 2016 19:18:26 UTC