[pt] Problem creating rule - 2021-07-04

Hello @udomai @jaumeortola

I have been trying to create the following rule:

	<!-- PORQUE É por ser -->
    <rule id='PORQUE_É_POR_SER' name="Porque é → Por ser" type="style">
    <!--      Created by Marco A.G.Pinto, Portuguese rule 2021-07-04 (25-JUN-2021+)      -->
	<!--
Difere da guerra porque o conflito é uma luta entre radicais. → Difere da guerra por o conflito ser uma luta entre radicais.
Difere da guerra porque os conflitos são uma luta entre radicais. → Difere da guerra por os conflitos serem uma luta entre radicais.
	-->
      <pattern>
		<marker>
			<token>porque</token>
			<token postag='DA.+' postag_regexp='yes'/>
			<token postag='NP.+|AQ0.+|NC.+' postag_regexp='yes'/>
			<token inflected='yes'>ser</token>
		</marker>
      </pattern>
      <message>Esta perífrase poderá ser simplificada.</message>
	  <suggestion>por \2 \3 <match no='4' postag='VMIP3S0' postag_regexp="yes" postag_replace='VMN03S0'/></suggestion>
	  <suggestion>por \2 \3 <match no='4' postag='VMIP3P0' postag_regexp="yes" postag_replace='VMN03P0'/></suggestion>
      <example correction="por o conflito ser">Difere da guerra <marker>porque o conflito é</marker> uma luta entre radicais.</example>
	  <example correction="por os conflitos serem">Difere da guerra <marker>porque os conflitos são</marker> uma luta entre radicais.</example>
    </rule>

But it suggests both plural and singular verb:

Exception in thread “main” org.languagetool.rules.patterns.PatternRuleTest$PatternRuleTestFailure: Test failure for rule PORQUE_É_POR_SER[1] in file /org/languagetool/rules/pt/grammar.xml: Incorrect suggestions: Expected ‘por o conflito ser’, got: ‘por o conflito ser|por o conflito serem’ on input: ‘Difere da guerra porque o conflito é uma luta entre radicais.’
at org.languagetool.rules.patterns.PatternRuleTest.addError(PatternRuleTest.java:339)
at org.languagetool.rules.patterns.PatternRuleTest.assertSuggestions(PatternRuleTest.java:593)
at org.languagetool.rules.patterns.PatternRuleTest.testBadSentences(PatternRuleTest.java:485)
at org.languagetool.rules.patterns.PatternRuleTest.lambda$testGrammarRulesFromXML$1(PatternRuleTest.java:368)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
org.languagetool.rules.patterns.PatternRuleTest$PatternRuleTestFailure: Test failure for rule PORQUE_É_POR_SER[1] in file /org/languagetool/rules/pt/grammar.xml: Incorrect suggestions: Expected ‘por os conflitos serem’, got: ‘por os conflitos ser|por os conflitos serem’ on input: ‘Difere da guerra porque os conflitos s?o uma luta entre radicais.’
at org.languagetool.rules.patterns.PatternRuleTest.addError(PatternRuleTest.java:339)
at org.languagetool.rules.patterns.PatternRuleTest.assertSuggestions(PatternRuleTest.java:593)
at org.languagetool.rules.patterns.PatternRuleTest.testBadSentences(PatternRuleTest.java:485)
at org.languagetool.rules.patterns.PatternRuleTest.lambda$testGrammarRulesFromXML$1(PatternRuleTest.java:368)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Could one of you give a tip on how to fix the suggestion verb?

Thanks!

Hi Marco!

You have two <suggestion> elements, which is why two suggestions are expected in the incorrect examples.

To only have the correct sg./pl. infinitive form, I would (1) specify the postags allowed in the fourth token (to avoid “sendo”, “sido”, “ser” etc.). Then, in the suggestion, you can do some regexp_replace magic so that only the P or S from \4 is kept.

That’s the quick answer without details (I’m kinda in a rush today), I hope it helps anyway :slight_smile:

@udomai

This is how it looks at the moment:

	<!-- PORQUE É por ser -->
    <rule id='PORQUE_É_POR_SER' name="Porque é → Por ser" type="style">
    <!--      Created by Marco A.G.Pinto, Portuguese rule 2021-07-04 (25-JUN-2021+)      -->
	<!--
Difere da guerra porque o conflito é uma luta entre radicais. → Difere da guerra por o conflito ser uma luta entre radicais.
Difere da guerra porque os conflitos são uma luta entre radicais. → Difere da guerra por os conflitos serem uma luta entre radicais.
	-->
      <pattern>
		<marker>
			<token>porque
				<exception scope='previous' postag_regexp='yes' postag='SPS.+'/>
			</token>
			<token/>
			<token postag='NP.+|AQ0.+|NC.+' postag_regexp='yes'/>
			<token inflected='yes'>ser
				<exception inflected='yes'>ir</exception>
			</token>
		</marker>
      </pattern>
      <message>Esta perífrase poderá ser simplificada.</message>
	  <suggestion>por \2 \3 <match no='4' postag='VMIP3S0' postag_regexp="yes" postag_replace='VMN03S0'/></suggestion>
	  <suggestion>por \2 \3 <match no='4' postag='VMIP3P0' postag_regexp="yes" postag_replace='VMN03P0'/></suggestion>
      <example correction="por o conflito ser|por o conflito serem">Difere da guerra <marker>porque o conflito é</marker> uma luta entre radicais.</example>
	  <example correction="por os conflitos ser|por os conflitos serem">Difere da guerra <marker>porque os conflitos são</marker> uma luta entre radicais.</example>
    </rule>

But I don’t know how to fix it.

Maybe @jaumeortola or @Ruud_Baars could help?

Thanks!

This is the best I could do and it still doesn’t work:

	<!-- PORQUE É por ser -->
    <rule id='PORQUE_É_POR_SER' name="Porque é → Por ser" type="style">
    <!--      Created by Marco A.G.Pinto, Portuguese rule 2021-07-04 (25-JUN-2021+)      -->
	<!--
Difere da guerra porque o conflito é uma luta entre radicais. → Difere da guerra por o conflito ser uma luta entre radicais.
Difere da guerra porque os conflitos são uma luta entre radicais. → Difere da guerra por os conflitos serem uma luta entre radicais.
	-->
      <pattern>
		<marker>
			<token>porque
				<exception scope='previous' postag_regexp='yes' postag='SPS.+'/>
			</token>
			<token/>
			<token postag='NP.+|AQ0.+|NC.+' postag_regexp='yes'/>
			<token inflected='yes'>ser
				<exception inflected='yes'>ir</exception>
			</token>
		</marker>
      </pattern>
      <message>Esta perífrase poderá ser simplificada.</message>
	  <suggestion>por \2 \3 <match no='4' postag='VMIP3.0' postag_regexp="yes" postag_replace='VMN03.0'/></suggestion>
      <example correction="por o conflito ser">Difere da guerra <marker>porque o conflito é</marker> uma luta entre radicais.</example>
	  <example correction="por os conflitos serem">Difere da guerra <marker>porque os conflitos são</marker> uma luta entre radicais.</example>
    </rule>

The essence in the first debug output is this:
Expected ‘por os conflitos serem’, got: ‘por os conflitos ser|por os conflitos serem’ on input: ‘Difere da guerra porque os conflitos são uma luta entre radicais.’

What is the output for the second try?

@Ruud_Baars

Thank you for your help.

The rule is supposed to change the verb at \4 from “VMIP3[SP]0” to “VMN03[SP]0”
So, in
“porque o conflito é” it should change the verb “é” to “ser”
“porque os conflitos são” it should change the verb “são” to “serem”.

Then it rearranges the words.

Thank you once again.

I am stuck on this rule before implementing/improving others.

VMIP3[SP]0 => VMN03[SP]0

VMIP3.0 => VMN03.0

If SP is specific, you could do

postag='VMIP3SP0' postag_regexp="yes" postag_replace='VMN03SP0'

if not, and it can have several values you want to keep, and has 2 characters, you could do:

postag='(VMIP3)(..)(0)' postag_regexp="yes" postag_replace='$1$2$3'

$2 specifies the second part of the original string, parts being specified by ()

@Ruud_Baars

I am so stressed! :slightly_frowning_face:

	<!-- PORQUE É por ser -->
    <rule id='PORQUE_É_POR_SER' name="Porque é → Por ser" type="style">
    <!--      Created by Marco A.G.Pinto, Portuguese rule 2021-07-04 (25-JUN-2021+)      -->
	<!--
Difere da guerra porque o conflito é uma luta entre radicais. → Difere da guerra por o conflito ser uma luta entre radicais.
Difere da guerra porque os conflitos são uma luta entre radicais. → Difere da guerra por os conflitos serem uma luta entre radicais.
	-->
      <pattern>
		<marker>
			<token>porque
				<exception scope='previous' postag_regexp='yes' postag='SPS.+'/>
			</token>
			<token/>
			<token postag='NP.+|AQ0.+|NC.+' postag_regexp='yes'/>
			<token inflected='yes'>ser
				<exception inflected='yes'>ir</exception>
			</token>
		</marker>
      </pattern>
      <message>Esta perífrase poderá ser simplificada.</message>
	  <suggestion>por \2 \3 <match no='4' postag='(VMIP3)(..)(0)' postag_regexp="yes" postag_replace='$1$2$3'/></suggestion>
      <example correction="por o conflito ser">Difere da guerra <marker>porque o conflito é</marker> uma luta entre radicais.</example>
	  <example correction="por os conflitos serem">Difere da guerra <marker>porque os conflitos são</marker> uma luta entre radicais.</example>
    </rule>

It throws errors on TESTRULES PT:

Testing rule 2700…
Skipped 0 rules for variant language to avoid checking rules more than once
2717 rules tested.
Exception in thread “main” org.languagetool.rules.patterns.PatternRuleTest$PatternRuleTestFailure: Test failure for rule PORQUE_É_POR_SER[1] in file /org/languagetool/rules/pt/grammar.xml: Incorrect suggestions: Expected ‘por o conflito ser’, got: ‘por o conflito (é)’ on input: ‘Difere da guerra porque o conflito é uma luta entre radicais.’
at org.languagetool.rules.patterns.PatternRuleTest.addError(PatternRuleTest.java:339)
at org.languagetool.rules.patterns.PatternRuleTest.assertSuggestions(PatternRuleTest.java:593)
at org.languagetool.rules.patterns.PatternRuleTest.testBadSentences(PatternRuleTest.java:485)
at org.languagetool.rules.patterns.PatternRuleTest.lambda$testGrammarRulesFromXML$1(PatternRuleTest.java:368)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
org.languagetool.rules.patterns.PatternRuleTest$PatternRuleTestFailure: Test failure for rule PORQUE_É_POR_SER[1] in file /org/languagetool/rules/pt/grammar.xml: Incorrect suggestions: Expected ‘por os conflitos serem’, got: ‘por os conflitos (s?o)’ on input: ‘Difere da guerra porque os conflitos s?o uma luta entre radicais.’
at org.languagetool.rules.patterns.PatternRuleTest.addError(PatternRuleTest.java:339)
at org.languagetool.rules.patterns.PatternRuleTest.assertSuggestions(PatternRuleTest.java:593)
at org.languagetool.rules.patterns.PatternRuleTest.testBadSentences(PatternRuleTest.java:485)
at org.languagetool.rules.patterns.PatternRuleTest.lambda$testGrammarRulesFromXML$1(PatternRuleTest.java:368)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Running disambiguator rule tests…
Running disambiguation tests for Portuguese…

@Ruud_Baars

It is solved:

<suggestion>por \2 \3 <match no='4' postag='(VM)(IP3)(.)(0)' postag_regexp="yes" postag_replace='$1N03$30'/></suggestion>

Thank you very much for your help!

Great. But do not stress without serious reasons…