[pt] Errors improving rule - 2019-12-02

Hello!

I have been improving Tiago’s rule:

<rulegroup id='GENERAL_NUMBER_AGREEMENT_ERRORS' name="Concordância de Número: Geral">

LINE 1062:

  <antipattern>
      <token postag='VMN0000'/>
      <token postag_regexp='yes' postag='AQ0[MFC]P0'/>
	  <token> <exception postag='DD0MS0' postag_regexp='no'/></token>
  </antipattern>

replaced with:

  <antipattern>
      <token postag_regexp='yes' postag='VMN0000|VMM02S0|VMSP3S0'/>
      <token postag_regexp='yes' postag='AQ0[MFC]P0|NC[MF]P000'/>
	  <token> <exception postag='DD0MS0' postag_regexp='no'/></token>
  </antipattern>

The idea was to make it work with:
Como o meu amigo Jörg disse: pouco importa se é placebo ou não, desde que dê resultados visíveis.

Como o meu amigo Jörg disse: pouco importa se é placebo ou não, desde que sê resultados visíveis.

Como o meu amigo Jörg disse: pouco importa se é placebo ou não, desde que vê resultados visíveis.

“dê”, “sê”, “vê” + plural

It works okay in the stand-alone tool, but if I issue a TESTRULES PT in gives several errors.

What is wrong with it?

Thanks!

It might be the space between > and <.

@Yakov

TESTRULES PT complains of the code below, even if I added one line with a possible suggestion:
<example correction='investigadores bons'>Queremos encontrar <marker>investigadores bom</marker>.</example>

Checking example sentences of 2503 rules for Portuguese…
Exception in thread “main” java.lang.AssertionError: Portuguese rule GENERAL_NUMBER_AGREEMENT_ERRORS[1]:
“Queremos encontrar investigadores bom.”
Errors expected: 1
Errors found : 0
Message: Possível erro de concordância de número.
Analyzed token readings: [/SENT_START*] Queremos[querer/VMIP1P0*] [ /null*] encontrar[encontrar/VMN0000] [ /null*] investigadores[investigador/AQ0MP0,investigador/NCMP000] [ /null*] bom[bom/AQ0MS0,bom/NCMS000] .[./SENT_END*,./_PUNCT*]
Matches:
at org.junit.Assert.fail(Assert.java:88)
at org.languagetool.rules.patterns.PatternRuleTest.testBadSentences(PatternRuleTest.java:363)
at org.languagetool.rules.patterns.PatternRuleTest.testGrammarRulesFromXML(PatternRuleTest.java:301)
at org.languagetool.rules.patterns.PatternRuleTest.runTestForLanguage(PatternRuleTest.java:157)
at org.languagetool.rules.patterns.PatternRuleTest.runGrammarRulesFromXmlTestIgnoringLanguages(PatternRuleTest.java:140)
at org.languagetool.rules.patterns.PatternRuleTest.main(PatternRuleTest.java:622)
Running disambiguator rule tests…
Running disambiguation tests for Portuguese…
Warning: At the moment, your platform (Windows) is not supported by the official XGBoost maven package; ML-based suggestion reordering is disabled.
370 rules tested (4265ms)
Tests successful.
Running XML bitext pattern tests…
Tests successful.
Validating false-friends.xml…
Validation successfully finished.

  <rulegroup id='GENERAL_NUMBER_AGREEMENT_ERRORS' name="Concordância de Número: Geral">
    <!--            General number concordance errors            -->
    <!-- Created by Tiago F. Santos, Portuguese rule, 2016-10-19 -->
      <url>https://pt.wikibooks.org/wiki/Portugu%C3%AAs/Concord%C3%A2ncia/Concord%C3%A2ncia_nominal</url>
      <antipattern case_sensitive='yes'>
          <unify negate='yes'><!-- XXX Proper names exception -->
            <feature id="gender"/><feature id="number"/>
          <token postag_regexp='yes' postag='(?:N|A).+|UNKNOWN' regexp='yes'>\p{Lu}.+</token>
          <token regexp='yes'>\p{Lu}.+</token>
          </unify>
      </antipattern>
      <antipattern>
          <unify negate='yes'>
            <feature id="number"/>
          <token postag_regexp='yes' postag='N.+'/>
          <token postag_regexp='yes' postag='Z.+'/>
          </unify>
      </antipattern>
      <antipattern>
          <token postag_regexp='yes' postag='VMN0000|VMM02S0|VMSP3S0'/>
          <token postag_regexp='yes' postag='AQ0[MFC]P0|NC[MF]P000'/>
		  <token><exception postag='DD0MS0' postag_regexp='no'/></token>
      </antipattern>
      <rule>
      <antipattern>
          <token regexp='yes'>(?:&precede_nome_proprio_F;|&precede_nome_proprio_M;)s?</token>
          <token regexp='yes' case_sensitive='yes'>\p{Lu}.+</token>
      </antipattern>
      <antipattern>
          <token>os</token>
          <token regexp='yes'>mais|menores|maiores|melhores|piores</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]P.+' postag_regexp='yes'/>
      </antipattern>
      <antipattern>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]S.+' postag_regexp='yes'/>
          <token regexp='yes'>d[eo]s?</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]P.+' postag_regexp='yes' max='2'/>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]S.+' postag_regexp='yes'/>
      </antipattern>
      <antipattern>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]S.+' postag_regexp='yes'/>
          <token regexp='yes'>d[eo]s?</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]P.+' postag_regexp='yes' max='2'/>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]S.+' postag_regexp='yes'/>
      </antipattern>
      <antipattern>
          <token>entre</token>
          <token regexp='yes'>[ao]s</token>
          <token>quais</token>
          <token postag='(?:NC|A..|Z.)[MC].+' postag_regexp='yes'/>
      </antipattern>
      <antipattern>
          <token>graus</token>
          <token regexp='yes'>Celsius|Kelvin|Fahrenheit</token>
      </antipattern>
      <antipattern>
          <token>quais</token>
          <token>um</token>
      </antipattern>
      <antipattern>
          <token>o</token>
          <token regexp='yes'>mais|menor|maior|pior|melhor</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]P.+' postag_regexp='yes'/>
          <token>possível</token>
      </antipattern>
      <antipattern>
          <token postag='(?:NC|A..)[MC]P.+' postag_regexp='yes'/>
          <token regexp='yes'>alvo|padrão</token>
      </antipattern>
      <pattern>
          <token negate='yes' regexp='yes'>&hifen;</token>
        <marker>
          <token postag='(?:D[ADIP].|NC|A..|P[^IDP].|Z.)[MC]P.+' postag_regexp='yes'>
            <exception postag='(?:D[ADIP].|N.|A..|P..|Z.)[MC][NS].+|(C|R).+|SPS00' postag_regexp='yes'/>
            <exception regexp='yes'>.+[°′″]</exception></token>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token><!-- XXX use POS after disambiguation improvements -->
          <token min='0' postag='(?:A..|Z.)C.+' postag_regexp='yes'>
            <exception negate_pos='yes' postag_regexp='yes' postag='(?:[NZ].|A..)C.+'/></token>
          <token postag='(?:[NZ].|A..)[MC]S.+' postag_regexp='yes'>
            <exception postag='(?:[NZ].|A..)[MC][NP].+|P[ID].[CFM].+|(C|R).+|SPS00.*|VMG0000' postag_regexp='yes'/>
            <exception regexp="yes">há|são|ser|haver|devido|vão|serão</exception>
            <exception scope='next' postag_regexp='yes' postag='[^Z].+' spacebefore='no' regexp='yes'>&hifen;</exception>
            <exception scope='next' postag_regexp='yes' postag='[^Z].+'>e</exception></token>
        </marker>
      </pattern>
      <message>&MSG_ECN;</message>
        <suggestion><match no='2' postag="(D[ADIP].|N.|A..|P[^IDP].|Z.)[MC]P(.+)" postag_replace='$1[MC]S$2' postag_regexp="yes"/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' include_skipped='all'/></suggestion>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' postag="(N.|[AD]..|Z.)[MC]S(.+)" postag_replace='$1[MC]P$2' postag_regexp="yes"/></suggestion>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/>, <match no='5' include_skipped='all'/></suggestion>
      <example correction='investigadores bons'>Queremos encontrar <marker>investigadores bom</marker>.</example>
	  <example correction='O cão bom|Os cães bons|Os, cão bom'><marker>Os cão bom</marker> estão no pasto.</example>
	  <example correction='O cão|Os cães|Os, cão'><marker>Os cão</marker> está no pasto.</example>
      <example correction="pai natal|pais natais|pais, natal">Havia <marker>pais natal</marker> na festa.</example>
      <example correction="todinho litoral|todo litoral|todinho, litoral|todo, litoral">Possui uma extensão aproximada de 378 km, o que representa 3,8% de <marker>todos litoral</marker> do México.</example>
      <example correction="caso mais preocupante|casos mais preocupantes|casos mais, preocupante">Os <marker>casos mais preocupante</marker> são estas.</example>
      <example>Conforme mais dados vão sendo acumulados de pessoas de todas as idades.</example>
      <example>Os rinocerontes serão anestesiados, antes de se remover o chifre.</example>
      <example>Calças, as mais rasgadas possível!</example>
      <example>Os montes Evereste, K2 e Kanchenjunga são os mais altos do mundo.</example>
      <example>As cores são: Ás de Copas vermelho, Ás de Ouros vermelho, Ás de Paus preto e Ás de Espadas preto.</example>
      <example>Os entendimentos têm de ser o mais amplos possível para serem efectivos.</example>
    </rule>
    <rule>
      <antipattern>
          <token postag_regexp='yes' regexp='yes' postag='R.+'>&contracoes_MP;
            <exception postag_regexp='yes' negate_pos='yes' postag='R.+'/></token>
      </antipattern>
      <pattern>
          <token negate='yes' regexp='yes'>&hifen;</token>
        <marker>
          <token regexp='yes'>&contracoes_MP;
            <exception>neles</exception>
            <exception postag_regexp='yes' postag='R.|NP.+'/></token>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token><!-- XXX use POS after disambiguation improvements -->
          <token min='0' postag='(?:A..|Z.)C.+' postag_regexp='yes'>
            <exception negate_pos='yes' postag_regexp='yes' postag='(?:[NZ].|A..)C.+'/></token>
          <token postag='(?:[NZ].|A..|DP.)[MC]S.+' postag_regexp='yes'>
            <exception postag='(?:[NZ].|A..|DP.)[MC][NP].+|NPMS.+|P[ID].[CFM].+|(C|R).+|SPS00|VMG0000' postag_regexp='yes'/>
            <exception regexp="yes">[dlv]ê|devido|m[éí]dia|há|haver|são|ser(?:ão)?</exception>
            <exception scope='next' postag_regexp='yes' postag='[^Z].+' spacebefore='no' regexp='yes'>&hifen;</exception>
            <exception scope='next' postag_regexp='yes' postag='[^Z].+'>e</exception></token>
        </marker>
      </pattern>
      <message>&MSG_ECN;</message>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' postag="(N.|[AD]..|Z.)[MC]S(.+)" postag_replace='$1[MC]P$2' postag_regexp="yes"/></suggestion>
      <example correction='dos pais'>É o orgulho <marker>dos pai</marker>.</example>
    </rule>
    <rule>
      <antipattern>
          <token regexp='yes'>(?:&precede_nome_proprio_F;|&precede_nome_proprio_M;)e?s?</token>
          <token regexp='yes' case_sensitive='yes'>\p{Lu}.+</token>
      </antipattern>
      <antipattern>
          <token regexp='yes'>tod[oa]</token>
          <token>ouvidos</token>
      </antipattern>
      <antipattern>
          <token>o</token>
          <token>quão</token>
      </antipattern>
      <antipattern>
          <token>o</token>
          <token regexp='yes'>mais|menor|maior|pior|melhor</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]P.+' postag_regexp='yes'/>
          <token>possível</token>
      </antipattern>
      <antipattern>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]P.+' postag_regexp='yes'/>
          <token regexp='yes'>d[eo]</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]S.+' postag_regexp='yes' max='2'/>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]P.+' postag_regexp='yes'/>
      </antipattern>
      <antipattern>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]P.+' postag_regexp='yes'/>
          <token regexp='yes'>d[eo]</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]S.+' postag_regexp='yes' max='2'/>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]P.+' postag_regexp='yes'/>
      </antipattern>
      <pattern>
          <token negate='yes' regexp='yes'>e|ou|&hifen;</token>
        <marker>
          <token postag='(?:D[ADIP].|NC|A..|P[^IDP].|Z.)[MC]S.+' postag_regexp='yes'>
            <exception postag='(?:D[ADIP].|N.|A..|Z.)[MC][NP].+|(C|R).+|SPS00|VMG0000' postag_regexp='yes'/>
            <exception>ás</exception><!-- XXX Dealt by HOMOPHONE_AS_CARD -->
            <exception regexp="yes">comer|há|haver|são|ser(?:ão)?|vão|uso|n</exception>
            <exception regexp='yes'>.+[°′″]</exception></token>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token><!-- XXX use POS after disambiguation improvements -->
          <token min='0' postag='(?:A..|Z.)C.+' postag_regexp='yes'>
            <exception negate_pos='yes' postag_regexp='yes' postag='(?:[NZ].|A..)C.+'/></token>
          <token postag='(?:[NZ].|A..)[MC]P.+' postag_regexp='yes'>
            <exception postag='(?:[NZ].|A..)[MC][NS].+|P[ID].[CFM].+|(C|R).+|SPS00.*' postag_regexp='yes'/></token>
        </marker>
          <token negate='yes' regexp='yes'>&hifen;</token>
      </pattern>
      <message>&MSG_ECN;</message>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' postag="(N.|[AD]..|Z.)[MC]P(.+)" postag_replace='$1[MC]S$2' postag_regexp="yes"/></suggestion>
        <suggestion><match no='2' postag="(D[ADIP].|N.|A..|P[^IDP].|Z.)[MC]S(.+)" postag_replace='$1[MC]P$2' postag_regexp="yes"/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' include_skipped='all'/></suggestion>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/>, <match no='5' include_skipped='all'/></suggestion>
      <example correction='Este gato|Estes gatos|Este, gatos'><marker>Este gatos</marker> estão no pasto.</example>
      <example>Sou todo ouvidos.</example>
      <example>Uso óculos desde os 6 anos,</example>
      <example>Calças, o mais possível rasgadas.</example>
      <example>O Monte Camarões é o vulcão mais ativo do oeste africano, tendo numerosas erupções registadas.</example>
      <example>O número nove.</example>
      <example>Lá fora estão zero graus.</example>
      <example>O escritor francês gostava de comer croissants na cama.</example>
      <example>Os entendimentos têm de ser o mais amplos possível para serem efectivos.</example>
    </rule>
    <rule>
      <antipattern>
          <token regexp='yes'>tod[oa]</token>
          <token>ouvidos</token>
      </antipattern>
      <antipattern>
          <token>do</token>
          <token regexp='yes'>8|oito</token>
          <token>para</token>
          <token min='0'>o</token>
          <token regexp='yes'>80|oitenta</token>
      </antipattern>
      <antipattern>
          <token postag_regexp='yes' regexp='yes' postag='R.+'>&contracoes_MS;
            <exception postag_regexp='yes' negate_pos='yes' postag='R.+'/></token>
      </antipattern>
      <pattern>
          <token negate='yes' regexp='yes'>e|ou|&hifen;</token>
        <marker>
          <token regexp='yes'>&contracoes_MS;
            <exception>nele</exception>
            <exception postag_regexp='yes' postag='R.|NP.+'/></token>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token><!-- XXX use POS after disambiguation improvements -->
          <token min='0' postag='(?:A..|Z.)C.+' postag_regexp='yes'>
            <exception negate_pos='yes' postag_regexp='yes' postag='(?:[NZ].|A..)C.+'/></token>
          <token postag='(?:[NZ].|A..|DP.)[MC]P.+' postag_regexp='yes'>
            <exception postag='(?:[NZ].|A..|DP.)[MC][NS].+|P[ID].[CFM].+|(C|R).+|SPS00.*' postag_regexp='yes'/></token>
        </marker>
          <token negate='yes' regexp='yes'>&hifen;</token>
      </pattern>
      <message>&MSG_ECN;</message>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' postag="(N.|[AD]..|Z.)[MC]P(.+)" postag_replace='$1[MC]S$2' postag_regexp="yes"/></suggestion>
        <suggestion>\2s <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' include_skipped='all'/></suggestion>
      <example correction='do pai|dos pais'>É o orgulho <marker>do pais</marker>.</example>
      <example correction='pelo meio|pelos meios'>Conseguiram combater o fogo <marker>pelo meios</marker> de todos os revezes.</example>
      <example>Pelo menos nós terminamos o trabalho pesado.</example>
    </rule>
    <rule>
      <antipattern>
          <token regexp='yes'>(?:&precede_nome_proprio_F;|&precede_nome_proprio_M;)e?s?</token>
          <token regexp='yes' case_sensitive='yes'>\p{Lu}.+</token>
      </antipattern>
      <antipattern>
          <token>a</token> <!-- FIXME Improve disambiguator for a as SP cases -->
          <token regexp='yes'>docentes|uma</token>
      </antipattern>
      <antipattern>
          <token>uma</token>
          <token>vez</token>
      </antipattern>
      <antipattern>
          <token>a</token>
          <token postag='Z.CN.+' postag_regexp='yes'/>
          <token regexp='yes'>&expressoes_de_tempo;|milhas|toneladas</token>
      </antipattern>
      <antipattern>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]P.+' postag_regexp='yes'/>
          <token regexp='yes'>d[eao]</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]S.+' postag_regexp='yes' max='2'/>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]P.+' postag_regexp='yes'/>
      </antipattern>
      <antipattern>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]P.+' postag_regexp='yes'/>
          <token regexp='yes'>d[eao]</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]S.+' postag_regexp='yes' max='2'/>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]P.+' postag_regexp='yes'/>
      </antipattern>
      <pattern>
          <token negate='yes' regexp='yes'>e|ou|&hifen;</token>
        <marker>
          <token postag='(?:D[ADIP].|NC|A..|P[^IDP].|Z.)[FC]S.+' postag_regexp='yes'>
            <exception postag='(?:D[ADIP].|N.|A..|Z.)[FC][NP].+|C.|R.' postag_regexp='yes'/>
            <exception regexp='yes'>.+[°′″]|leva|continha|mediante</exception></token>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token><!-- XXX use POS after disambiguation improvements -->
          <token min='0' postag='(?:A..|Z.)C.+' postag_regexp='yes'>
            <exception negate_pos='yes' postag_regexp='yes' postag='(?:[NZ].|A..)C.+'/></token>
          <token postag='(?:[NZ].|A..)[FC]P.+' postag_regexp='yes'>
            <exception postag='(?:[NZ].|A..)[FC][NS].+|P[ID].[CFM].+|(C|R).+|SPS00.*' postag_regexp='yes'/></token>
        </marker>
          <token negate='yes' regexp='yes'>&hifen;</token>
      </pattern>
      <message>&MSG_ECN;</message>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' postag="(N.|[AD]..)[FC]P(.+)" postag_replace='$1[FC]S$2' postag_regexp="yes"/></suggestion>
        <suggestion><match no='2' postag="(D[ADIP].|N.|A..)[FC]S(.+)" postag_replace='$1[FC]P$2' postag_regexp="yes"/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' include_skipped='all'/></suggestion>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/>, <match no='5' include_skipped='all'/></suggestion>
      <example correction='A vaca|As vacas|A, vacas'><marker>A vacas</marker> são malhadas.</example>
      <example>O programa Lendas do Futuro é bom?</example>
      <example>Uma vez acordadas as novas condições, será feito o abastecimento elétrico.</example>
      <example correction='união empobrecida|uniões empobrecidas|união, empobrecidas'>As regiões na <marker>união empobrecidas</marker> acabaram por ser culpabilizadas.</example>
      <example>As regiões da <marker>união empobrecidas</marker> acabaram por ser culpabilizados.</example>
      <example>…odo estudante confia no Sr. Akai porque ele nunca quebra promessas.</example>
      <example correction='bastante mesa|bastantes mesas|bastante, mesas'>Existem <marker>bastante mesas</marker>!</example>
      <example>Algo que nos une como plataforma a tantos continentes, a tantos oceanos, a tantas culturas, a tantas civilizações</example>
    </rule>
    <rule>
      <antipattern>
          <token postag_regexp='yes' regexp='yes' postag='R.+'>&contracoes_FS;
            <exception postag_regexp='yes' negate_pos='yes' postag='R.+'/></token>
      </antipattern>
      <pattern>
          <token negate='yes' regexp='yes'>e|ou|&hifen;</token>
        <marker>
          <token regexp='yes'>&contracoes_FS;
            <exception>nela</exception>
            <exception postag_regexp='yes' postag='R.|NP.+'/></token>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token><!-- XXX use POS after disambiguation improvements -->
          <token min='0' postag='(?:A..|Z.)C.+' postag_regexp='yes'>
            <exception negate_pos='yes' postag_regexp='yes' postag='(?:[NZ].|A..)C.+'/></token>
          <token postag='(?:[NZ].|A..|DP.)[FC]P.+' postag_regexp='yes'>
            <exception postag='(?:[NZ].|A..|DP.)[FC][NS].+|P[ID].[CFM].+|(C|R).+|SPS00.*' postag_regexp='yes'/></token><!-- FIXME Review patterns to include passive without crippling detection -->
        </marker>
          <token negate='yes' regexp='yes'>&hifen;</token>
      </pattern>
      <message>&MSG_ECN;</message>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' postag="(N.|[AD]..|Z.)[FC]P(.+)" postag_replace='$1[FC]S$2' postag_regexp="yes"/></suggestion>
        <suggestion>\2s <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' include_skipped='all'/></suggestion>
      <example correction='numa espécie|numas espécies'>Valor contido <marker>numa espécies</marker> por descobrir.</example>
    </rule>
    <rule>
      <antipattern>
          <token regexp='yes'>(?:&precede_nome_proprio_F;|&precede_nome_proprio_M;)s?</token>
          <token regexp='yes' case_sensitive='yes'>\p{Lu}.+</token>
      </antipattern>
      <antipattern>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]S.+' postag_regexp='yes'/>
          <token regexp='yes'>d[eao]s?</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]P.+' postag_regexp='yes' max='2'/>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token>
    <!--token min='0' postag='(?:A..|Z.)C.+' postag_regexp='yes'-->
          <token postag='(?:D[ADIP].|NC|A..|Z.)[MC]S.+' postag_regexp='yes'/>
      </antipattern>
      <antipattern>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]S.+' postag_regexp='yes'/>
          <token regexp='yes'>d[eao]s?</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]P.+' postag_regexp='yes' max='2'/>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token>
    <!--token min='0' postag='(?:A..|Z.)C.+' postag_regexp='yes'-->
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]S.+' postag_regexp='yes'/>
      </antipattern>
      <antipattern>
          <token>distribuições</token>
          <token>Linux</token>
      </antipattern>
      <antipattern>
          <token postag_regexp='yes' postag='N..P.+'/><!-- XXX if this noun is part of a nominal group assume 'era' as a VERB-->
          <token>era</token>
      </antipattern>
      <antipattern>
          <token postag='(?:NC|A..)[FC]P.+' postag_regexp='yes'/>
          <token regexp='yes'>base|chave</token>
      </antipattern>
      <antipattern>
          <token>o</token>
          <token regexp='yes'>mais|menor|maior|pior|melhor</token>
          <token postag='(?:D[ADIP].|NC|A..|Z.)[FC]P.+' postag_regexp='yes'/>
          <token>possível</token>
      </antipattern>
      <pattern>
          <token negate='yes' regexp='yes'>&hifen;</token>
        <marker>
          <token postag='(?:D[ADIP].|NC|A..|P[^IDP].|Z.)[FC]P.+' postag_regexp='yes'>
            <exception postag='(?:D[ADIP].|N.|A..|Z.)[FC][NS].+|(C|R).+|SPS00' postag_regexp='yes'/>
            <exception regexp='yes'>.+[°′″]|levas|vezes</exception></token>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token><!-- XXX use POS after disambiguation improvements -->
          <token min='0' postag='(?:A..|Z.)C.+' postag_regexp='yes'>
            <exception negate_pos='yes' postag_regexp='yes' postag='(?:[NZ].|A..)C.+'/></token>
          <token postag='(?:[NZ].|A..)[FC]S.+' postag_regexp='yes'>
            <exception postag='(?:[NZ].|A..)[FC][NP].+|P[ID].[CFM].+|(C|R).+|SPS00.*' postag_regexp='yes'/>
            <exception scope='next' postag_regexp='yes' postag='[^Z].+' spacebefore='no' regexp='yes'>&hifen;</exception>
            <exception scope='next' postag_regexp='yes' postag='[^Z].+'>e</exception></token>
        </marker>
      </pattern>
      <message>&MSG_ECN;</message>
        <suggestion><match no='2' postag="(D[ADIP].|N.|A..|P[^IDP].|Z.)[FC]P(.+)" postag_replace='$1[FC]S$2' postag_regexp="yes"/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' include_skipped='all'/></suggestion>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' postag="(N.|[AD]..|Z.)[FC]S(.+)" postag_replace='$1[FC]P$2' postag_regexp="yes"/></suggestion>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/>, <match no='5' include_skipped='all'/></suggestion>
      <example correction='A vaca|As vacas|As, vaca'><marker>As vaca</marker> são malhadas.</example>
      <example>Apresentou os programas Jornal do Mundo, Internacional Patati e Plus Berlin.</example>
      <example correction='fechadura grande|fechaduras grandes|fechaduras, grande'>Coloca essa chave nas <marker>fechaduras grande</marker>.</example>
      <example correction="situação mais preocupante|situações mais preocupantes|situações mais, preocupante">A <marker>situações mais preocupante</marker> é esta.</example>
      <example>Conforme mais dados vão sendo acumulados de pessoas de todas as idades.</example>
      <example>Pega na chave das <marker>fechaduras grande</marker>.</example>
      <example>As respostas têm de ser o mais amplas possível para serem efectivos.</example>
    </rule>
    <rule>
      <antipattern>
          <token postag_regexp='yes' regexp='yes' postag='R.+'>&contracoes_FP;
            <exception postag_regexp='yes' negate_pos='yes' postag='R.+'/></token>
      </antipattern>
      <pattern>
          <token negate='yes' regexp='yes'>&hifen;</token>
        <marker>
          <token regexp='yes'>&contracoes_FP;
            <exception regexp='yes'>mas|nelas</exception>
            <exception postag_regexp='yes' postag='R.|NP.+'/></token>
          <token regexp='yes' min='0'>&adverbios_de_intensidade;</token><!-- XXX use POS after disambiguation improvements -->
          <token min='0' postag='(?:A..|Z.)C.+' postag_regexp='yes'>
            <exception negate_pos='yes' postag_regexp='yes' postag='(?:[NZ].|A..)C.+'/></token>
          <token postag='(?:[NZ].|A..|DP.)[FC]S.+' postag_regexp='yes'>
            <exception postag='(?:[NZ].|A..|DP.)[FC][NP].+|P[ID].[CFM].+|(C|R).+|SPS00.*' postag_regexp='yes'/>
            <exception scope='next' postag_regexp='yes' postag='[^Z].+' spacebefore='no' regexp='yes'>&hifen;</exception>
            <exception scope='next' postag_regexp='yes' postag='[^Z].+'>e</exception></token>
        </marker>
      </pattern>
      <message>&MSG_ECN;</message>
        <suggestion><match no='2' include_skipped='all'/> <match no='3' include_skipped='all'/> <match no='4' include_skipped='all'/> <match no='5' postag="(N.|[AD]..|Z.)[FC]S(.+)" postag_replace='$1[FC]P$2' postag_regexp="yes"/></suggestion>
      <example correction='numas espécies'>Valor contido <marker>numas espécie</marker> por descobrir.</example>
    </rule>
    <rule>
      <antipattern>
          <token>a</token>
          <token regexp='yes'>ambos|est[ea]s</token>
      </antipattern>
      <pattern>
          <unify negate="yes">
            <feature id="number"/>
          <token postag_regexp='yes' postag='D.+'>
            <exception postag_regexp='yes' postag='D.+' negate_pos='yes'/></token>
          <token postag_regexp='yes' postag='D.+'>
            <exception postag_regexp='yes' postag='D.+' negate_pos='yes'/></token>
          </unify>
      </pattern>
      <message>&MSG_ECN;</message>
        <suggestion><match no='1' postag='D(...).(.+)' postag_replace='D$1S$2' postag_regexp='yes'/> <match no='2' postag='D(...).(.+)' postag_replace='D$1S$2' postag_regexp='yes'/></suggestion>
        <suggestion><match no='1' postag='D(...).(.+)' postag_replace='D$1P$2' postag_regexp='yes'/> <match no='2' postag='D(...).(.+)' postag_replace='D$1P$2' postag_regexp='yes'/></suggestion>
      <example correction="A nossa|As nossas"><marker>As nossa</marker> equipa de operações está muito focada nos campos de verão..</example>
    </rule>
  </rulegroup>

Do you know what is wrong?

Thanks!

@Yakov @dnaber @tiff

Any comments on this?

Thanks!

I tried replacing the suggestion line with:

<example correction='dê resultados'>Pouco importa se é placebo, desde que <marker>dê resultado</marker> visíveis.</example>

But in TESTRULES PT I still get:

Checking example sentences of 2503 rules for Portuguese…
Exception in thread “main” java.lang.AssertionError: Portuguese rule GENERAL_NUMBER_AGREEMENT_ERRORS[1]:
“Pouco importa se é placebo, desde que dê resultado visíveis.”
Errors expected: 1
Errors found : 0
Message: Possível erro de concordância de número.
Analyzed token readings: [/SENT_START*] Pouco[pouco/NCMS000*,pouco/PI0MS000*] [ /null*] importa[importar/VMIP3S0,importar/VMM02S0] [ /null*] se[se/CS,se/PP3CN000] [ /null*] é[ser/VMIP3S0] [ /null*] placebo[placebo/NCMS000] ,[,/_PUNCT*] [ /null*] desde[desde/CS] [ /null*] que[que/CS] [ /null*] dê[dê/NCMS000,dar/VMM03S0,dar/VMSP1S0,dar/VMSP3S0] [ /null*] resultado[resultado/NCMS000,resultar/VMP00SM] [ /null*] visíveis[visível/AQ0CP0] .[./SENT_END*,./_PUNCT*]
Matches:
at org.junit.Assert.fail(Assert.java:88)
at org.languagetool.rules.patterns.PatternRuleTest.testBadSentences(PatternRuleTest.java:363)
at org.languagetool.rules.patterns.PatternRuleTest.testGrammarRulesFromXML(PatternRuleTest.java:301)
at org.languagetool.rules.patterns.PatternRuleTest.runTestForLanguage(PatternRuleTest.java:157)
at org.languagetool.rules.patterns.PatternRuleTest.runGrammarRulesFromXmlTestIgnoringLanguages(PatternRuleTest.java:140)
at org.languagetool.rules.patterns.PatternRuleTest.main(PatternRuleTest.java:622)
Running disambiguator rule tests…
Running disambiguation tests for Portuguese…
Warning: At the moment, your platform (Windows) is not supported by the official XGBoost maven package; ML-based suggestion reordering is disabled.
370 rules tested (1861ms)
Tests successful.
Running XML bitext pattern tests…
Tests successful.
Validating false-friends.xml…
Validation successfully finished.

@danielnaber @Yakov @Ruud_Baars

I seem to have been able to fix it:

Will check the diff tomorrow night.

Thanks for all the trouble.

Ок!