Jump to content

Wikifunctions:Type proposals/Syntactic table

From Wikifunctions
Experimentally implemented: (experimental) Syntactic table (Z36462): captures a part of a sentence that still might have a number of different options when realized and might already have some features determined --DVrandecic (WMF) (talk) 12:49, 17 June 2026 (UTC)reply

One aim of the NLG system is to have a small number of language-specific functions. It is OK to have many abstract functions, but the specific languages should ideally be less numerous.

For example, consider the following six outputs:

  1. Brač is an island.
  2. Brač is a beautiful island.
  3. Brač is a beautiful island.
  4. Brač is an island.
  5. Brač is a beautiful island.
  6. Brač is a beautiful island.

How many language-specific functions would that need?

If I look at the current best practices, I seem to land on six language-specific functions, one for each output. Even though grammatically there seem to be only two major operations:

  • Connect two noun phrases in a predicative sentence: Brač is an island
  • Combine an adjective and a noun to form a noun phrase: a beautiful island

Besides that, we would have functions to turn a phrase into a link or to give strong emphasis to a phrase, but do these need to be language-specific? I think not.

We seem to have all the necessary pieces for the outputs already available:

But it is currently not possible to plug these together to allow for the creation of the outputs above, beyond the first one.

That’s partially because of the involved types:

  • indefinite noun phrase with adjective takes two Wikidata item references and a language and returns a string
  • article-less instantiating fragment does the same
  • Strong importance takes a string and returns an HTML fragment
  • HTML link to Wikipedia article about Wikidata item takes a language and a Wikidata item reference and returns an HTML fragment

It seems that what we would want to do is the following (the language parameter has been omitted for legibility):

  1. instantiating( Brač, island )
  2. instantiating( Brač, noun with adjective( island, beauty ) )
  3. instantiating( Brač, noun with adjective( link( island ), beauty ) )
  4. instantiating( strong( Brač ), island )
  5. instantiating( strong( Brač ), noun with adjective( island, beauty ) )
  6. instantiating( strong( Brač ), noun with adjective( link( island ), beauty ) )

If we want to be able to do this, the type of Brač and the return type of strong must be the same, as well as the type of island and the return types of link and noun with adjective.

What could that type be?

In English, as usual, we may get seduced to a certain simplicity: we could probably just use HTML fragment as the type and probably get away with it! All of the operations above seem to work out.

But in French (or Italian or Spanish or many other languages) that wouldn’t work: noun with adjective needs to know the gender of the noun in order to select the right form of the adjective (the adjective and the noun need to agree with each other). HTML fragment does not provide that information.

I don’t think that there currently is a good type for that. I suggest introducing a new type, the syntactic table. This is inspired by Grammatical Framework, and in core similar to a proposal I made last year, but I learned a lot from the comments and modified the type accordingly, making it considerably simpler.

Syntactic table has the following four keys:

  1. Language, i.e. which natural language is this table for
  2. Part of speech, i.e. which part of speech is this (noun, noun phrase, verb, adjective, etc.) (is this a lightweight enumeration or a Wikidata item reference?)
  3. Inherent features, list of Wikidata item references representing grammatical features, e.g. masculine, plural, etc.
  4. Options, a list of pairs of a list of Wikidata item references (representing grammatical features) and a list of HTML fragments

Or, do visualize it, here is a visualization of the syntactic table for the German noun “Stadt”, meaning city.

language German
Part of speech noun
Inherent feature feminine
options nominative genitive dative accusative
singular Stadt Stadt Stadt Stadt
plural Städte Städte Städten Städte

And here is a partial visualization of the syntactic table for the German adjective “schön”, meaning beautiful.

language German
Part of speech adjective
Inherent feature
options singular plural
masculine feminine neuter
nominative schöner schöne schönes schönen
genitive schönen schönen schönen schönen
dative schönen schönen schönen schönen
accusative schönen schöne schönes schönen

Now there would be a number of functions working on syntactic tables: for example, the merge function, which takes two tables and returns a table, representing the merger.

The inherent features of each of the tables are used to filter the options in each other tables. In addition, the options are combined together to create a new map of forms. So the result of the merging the two tables with a simple spaced concatenation would be:

language German
Part of speech core noun phrase
Inherent feature feminine
options nominative genitive dative accusative
singular schöne Stadt schönen Stadt schönen Stadt schöne Stadt
plural schönen Städte schönen Städte schönen Städten schönen Städte

Another function could be used to bold a part of the text (which is a mostly language-independent operation). So we might have bolded the noun ‘Stadt’ before, which would result in the following output:

language German
Part of speech noun
Inherent feature feminine
options nominative genitive dative accusative
singular Stadt Stadt Stadt Stadt
plural Städte Städte Städten Städte

If we merge that with the adjective as before, we get the following result:

language German
Part of speech core noun phrase
Inherent feature feminine
options nominative genitive dative accusative
singular schöne Stadt schönen Stadt schönen Stadt schöne Stadt
plural schönen Städte schönen Städte schönen Städten schönen Städte

And if we merge that with an indefinite article, we get a full noun phrase:

language German
Part of speech noun phrase
Inherent feature feminine
options nominative genitive dative accusative
singular eine schöne Stadt einer schönen Stadt einer schönen Stadt eine schöne Stadt
plural schönen Städte schönen Städte schönen Städten schönen Städte

Note that we are always operating on syntactic tables, both in the input and in the output, allowing us to combine the functions flexibly.

Compared to my previous proposal, we would not be creating hundreds of types, but just a small number (one basically, maybe some supporting types), answering one of the biggest criticisms. Also, the new type will be available immediately for all languages that want to use it.

To summarize, the idea is to have two kind of functions: functions that are usable across all (or at least most) languages (such as link or strong emphasis) and functions that need to be implemented in each language (such as noun with adjective). Both can use the same type, and thus be combined in a way that can reduce the number of functions in the latter group.

Discusssion

Cory's thoughts

This proposal can get us very far for languages with simple (-ish) morphologies. It will be less effective for morphologically rich language, where a syntactic table might contain thousands of forms, and where it might be more natural to apply these kinds of transformations only to parts of words. For example, while some languages might be okay with

schönen <bold>Städte</bold>

others might prefer something like

schönen <bold>Städt</bold>e

(note the "e" standing outside of the bold chunk). This can even happen in English: if we wanted to make the phrasal verb "pick up" bold in a sentence, we'd have to deal with non-consecutive bold tokens, e.g.

Please <bold>pick</bold> it <bold>up</bold>.

More broadly, NLP systems tend to handle this kind of metadata in one of two ways: offset and inset annotation. Inset annotation looks like the above examples: tags that intervene directly in a data structure. Offset annotation might look more like this:

{
  "text": "Please pick it up.",
  "spans": [
    { "tag": "bold", "begin": 7, "end": 11 },
    { "tag": "bold", "begin": 15, "end": 17 }
  ]
}

Decisions like this are not unrelated to how we decide to represent linguistic elements more generally. A general, robust solution would involve treating linguistic units not as literal text strings but as symbolic transformational nodes. In this case, the system wouldn't operate over "Stadt" but over a richer structure containing 1) the syntactic usage of "Stadt," 2) the eventual inflected form of "Stadt," and 3) any additional annotations, such as bold text, that should be applied to the token.

It is also possible for these two paradigms to play nicely together. At the end of the day, our system will need to produce specific surface forms in sequence to create sentences, but how we get to those surface forms can vary. Some languages might use syntactic tables while others might need to function in terms of symbolic morphological transformations (if only to reduce the search space of possible syntactic tables!).

Further thoughts by Denny

Cory’s point is valid. In some languages, we will easily get to hundreds of forms. That may not be feasible. Questions are whether we can avoid to expand all these forms, or whether, maybe with a smart usage of quoting functions or some other mechanism, we can find a way to scale the system.

Alternatives

Comments

  • Support Support: this isn't perfect, but it's much much better. Feeglgeef (talk) 16:32, 2 April 2026 (UTC) Neutral Neutral: I'd like more opporitunity to review the two competing proposals on this topic, which one we go with is important. Feeglgeef (talk) 13:59, 10 April 2026 (UTC)reply
  • Support Support I feel that this is a step that's required for handling different types of phrases. John Samuel 17:59, 2 April 2026 (UTC)reply
  • Support Support I like the idea as I really like spreadsheet functions and tables. As I like Boilerplate templates I hope this proposal can help making it easier to create a function for a specific sentence representing some Wikidata statements.--Hogü-456 (talk) 16:17, 3 April 2026 (UTC)reply
  • Neutral Comment I'm skeptical that we can attain general prose in non-European languages even with this extra context.
    Looking at your example of noun_with_adjective[de] := (noun, adj) => matrix_product(concat_with_space)(adj, noun), each of the cells/entries in the table is a single Z89, so it seems this Type is limited to grammars where applying an adjective to a noun is just a prefix and/or suffix. I've previously remarked that counters in Japanese can "migrate" to the verb (unlike in English, German, etc. where counters behave like adjectives). To accommodate this, either the language-specific merge Function would have to parse and split off the counter when embedding the noun phrase into a sentence, or this Type would have to somehow encode a split result with additional tagging on each segment.
    IMO a better model for applying formatting like boldface and hyperlinks would be as Z882(Z11, Z883(Z6091, Z881(Z882(Z13518, Z13518)))), that is, to do all linguistic processing on plaintext, but keep track of which span(s) in the string corresponds to each Item from the outer callsite. Then that outer Function can format and linkify the final string by iterating those ranges as ordered by their start index. edit: abstract:Project:Abstract article architectures#Modest improvement to current architecture using spans YoshiRulz (talk) 17:53, 3 April 2026 (UTC)reply
  • Oppose Weakly oppose While I completely support the need to scale NLG functions outside simple fragment generating functions, I'm skeptical on the bottom-up approach that syntactic tables use. As already addressed, starting composing a sentence from the constituent parts is problematic, since in many instances the behaviour of a part of the sentence depends in non trivial ways to the entire structure of the sentence (in ways that are sometimes not neatly encodable in a simple table). I think that usually the best approach for NLG is top-down, which means that a function should try to generate an entire sentence, delegating to other functions the generation of parts of a sentence (providing the necessary grammatical context). When I have time, I'll try to formulate an alternative proposal. This type could still be a useful intetnal tool, but I think using it as the foundation for modular NLG can be very problematic. Dv103 (talk) 15:14, 5 April 2026 (UTC)reply
    I've now formulated the proposal for Wikifunctions:Type proposals/Abstract sentence Dv103 (talk) 12:22, 7 April 2026 (UTC)reply
  • Oppose Oppose per YoshiRulz and Dv103; I have started proposing types based on my own efforts at language generation at ,Wikifunctions:Type proposals/Syntactic unit and Wikifunctions:Type proposals/Semantic unit. Mahir256 (talk) 17:54, 5 April 2026 (UTC)reply
    Thanks for the links :) So9q (talk) 21:00, 5 April 2026 (UTC)reply
  • I’m not opposed to this proposal, but I do question the wisdom of characterizing a type without formalizing it. We already see the inconvenience with Monolingual text (Z11), where we are unable to identify that a function is limited to a particular language. For what are logically more constrained functions, I think the “too many types” is a valid objection, but if types have no part to play in managing the inevitable complexity, what is the alternative?
I hesitate to leap to solutions, but we should at least explore “generic” types here. In any event, I believe we should make some distinction at the type level, based on the syntactic category (“part of speech” in the proposal). For example, constructions that (logically) require a noun phrase for a particular argument should resist having that argument provided by a function that returns a verb phrase (which would need to be wrapped in a nominalization function). That looks and feels like type-handling, of course, but the real question remains: If syntactic categories are not represented by persistent or generic types, how are the constraints associated with those categories represented and enforced, particularly when constructing compositions, as opposed to evaluating them.
GrounderUK (talk) 10:16, 17 June 2026 (UTC)reply
I think these are great questions. My favorite proposal is still to create specific types for (English / French / Dagbani / ...) (nouns / verb / noun phrase / adjective / ...), in addition to abstract (noun / verb / noun phrase / adjective ...), but there was too much pushback on that one.
My sense is that we can kick off this one (I did so yesterday) and try it out. We can later still switch to a "many types" solution, most of the functions would be basically the same. --Denny (talk) 12:47, 17 June 2026 (UTC)reply
Yes. As I say, I’m not opposed; I just think that we should expect to end up with “many” types, with whichever structures, whether or not we factor out the language. As I understand the proposal, the complex “generic” type of a K4 object would be the same in every instance, so it is purely structural, with no surfacing of the permitted or expected combinations. Is that right? GrounderUK (talk) 13:58, 17 June 2026 (UTC)reply
that's correct, K4 is purely structural. One could write functions that check that the table for an English noun is all correct, but as a datatype it is not aware of it. --Denny (talk) 13:05, 22 June 2026 (UTC)reply
That's actually a good idea, I implemented is valid English noun table (Z36770) in order to validate English nouns, as an example. --Denny (talk) 13:26, 22 June 2026 (UTC)reply

Oppose Oppose It seems likely that it'll work for English, and I'll accept Denny's claim that it works for German, but other languages will run into problems because this only deals with syntax, not semantics. To visualize the issue, let's look at the Spanish syntactic tables for the noun "amigo" (friend) and the adjective "viejo" (old):

language Spanish
Part of speech noun
Inherent feature masculine
options
singular amigo
plural amigos
language Spanish
Part of speech adjective
Inherent feature -
options singular plural
masculine feminine masculine feminine
viejo vieja viejos viejas

The hypothetical merge function, following the common rule for Spanish word order, might produce the following:

language Spanish
Part of speech core noun phrase
Inherent feature masculine
options
singular amigo viejo
plural amigos viejos

But there's a problem: this table only represents half the possible meanings for combining the words "amigo" and "viejo". If you combine them in the other order, you get this table:

language Spanish
Part of speech core noun phrase
Inherent feature masculine
options
singular viejo amigo
plural viejos amigos

The two don't mean the same thing. "Viejo amigo" means "old (=long-time) friend", while "amigo viejo" means "old (=elderly) friend". And "viejo" is hardly the only adjective with this property; I can purchase a "nuevo carro" from a used-car salesman.

This is all without getting into higher-level functions. instantiating() (Wiktionary "be" definition 2.3) might be reasonably simple in Spanish, but attributive() (Wiktionary "be" 2.4) requires a whole mess of semantic metadata to select the correct verb (for example, "está sucio" can be remedied by washing, while "es sucio" can't). --Carnildo (talk) 05:44, 16 August 2026 (UTC)reply