Como criar ou modificar regras

O CoGrOO suporta regras escritas em formato XML, e para casos mais específicos é possível criar regras em código Java.

Sempre prefira o formato XML, pois o código é bastante otimizado para aplicar essas regras. No entanto, existem casos em que isto não é possível, então siga para regras em código Java.

Regras em XML

Elementos envolvidos

  • source:cogroo3/trunk/CoGrOOBase/src/main/rules/rules.xml
    • É o arquivo fonte onde as regras são descritas.
  • source:cogroo3/trunk/CoGrOOBase/src/main/rules/rules.serialized
    • Ele é a serialização de um objeto do tipo br.usp.pcs.lta.cogroo.tools.checker.rules.applier.RulesTrees construido a partir de rules.xml. A construção dessa classe é lenta, por isso é preferível gerar ela em tempo de desenvolvimento e salvar serializada.
  • source:cogroo3/trunk/CoGrOOBase/src/main/resources/br/usp/pcs/lta/cogroo/tools/checker/rules/rules.properties
    • Arquivo com opções para a aplicação das regras. Configure aqui se deseja regerar o a classe RulesTrees sempre, apesar de lenta, essa opção é bastante útil para testar alterações no arquivo rules.xml
  • source:cogroo3/trunk/CoGrOOBase/src/main/resources/br/usp/pcs/lta/cogroo/tools/checker/rules/template-fromxml-rules.properties
    • Exemplo de rules.properties configurado para usar diretamente o rules.xml, e reler esse arquivo depois de cada requisição do corretor gramatical.
  • source:cogroo3/trunk/CoGrOOBase/src/main/resources/br/usp/pcs/lta/cogroo/tools/checker/rules/template-production.rules.properties
    • Exemplo de rules.properties configurado para melhor desempenho. Usar esse para os builds release.
  • source:cogroo3/trunk/CoGrOOBase/src/main/rules/rules.xsd
    • Descreve como o rules.xml deve ser formatado.

Preparando o ambiente de desenvolvimento

  • Substitua o conteúdo de rules.properties pelo conteúdo de template-fromxml-rules.properties.
  • Refaça o build do base.
  • Faça as suas alterações e no Eclipse teste usando Run >> Debug Configurations >> Java Applications >> CogrooMain.
  • Alternativamente você pode testar usando Linha de Comando. Você também pode alterar direto o arquivo da distribuição rules/rule.xml.
  • Caso prefira, faça as alterações direto no arquivo cogroo\target\cogroo-3.0.2-SNAPSHOT-bin.dir\rules\rules.xml. Caso altere /cogroo/src/main/rules/rules.xml, será necessário fazer um novo build antes de testar. Lembre que cogroo\target\cogroo-3.vv.vv-SNAPSHOT-bin.dir\rules\rules.xml é alterado durante o build e você pode perder suas alterações. Usando esse método. Depois de testar o rules.xml, copie suas alterações para /cogroo/src/main/rules/rules.xml
  • Sugestão: pode ser mais fácil se você isolar sua nova regra no arquivo rules.xml, comentando ou excluindo as demais regras.

Criando uma regra

Veja detalhes de como criar uma regra em Criando regras XML

Regras em Java

O CoGrOO tem um mecanismo de plugar regras Java. Basta implementar uma instância de Checker.java ou AbstractChecker.java e configurar o arquivo rules.properties.

Esse mecanismo é bom para implementar coisas que ficam complicadas escrever no formato rules.xml, por exemplo: balanceamento de parênteses, procurar palavras duplicadas e regras mais sofisticadas de regência verbal. Ficam como sugestões para quem quiser se aventurar e criar um novo Checker.

Implementar instância de Checker:

public interface Checker {

    public String getIdPrefix();

    public List<Mistake> check(Sentence sentence);

    public void ignore(String id);

    public void resetIgnored();

    public int getPriority();

    public Collection<RuleDefinitionI> getRulesDefinition();
}

O método mais importante é o check(Sentence), que recebe uma sentença por vez, e devolve uma lista de erros.

Cada Checker pode implementar muitas regras internamente. Cada uma precisa ter um ID diferente, mas todas com um mesmo prefixo. A implementação deve informar qual é esse prefixo pelo método getIdPrefix(). Exemplo: uma regra pode ter id space:MISSING_SPACE e outra space:TOO_MANY_SPACES; nesse caso o prefixo é space:.

O prefixo é importante para direcionar o comando ignore(String) para o Checker correto. A implementação de Checker deve cuidar do mecanismo de ignorar e resetar.
Finalmente getPriority() indica a prioridade desse Checker. Quanto maior o valor retornado, maior a prioridade.

O método getRulesDefinition() deve retornar uma coleção de definições de regra. São dados necessários para exibir informações ao usuário sobre quais regras são implementadas.

Usando o AbstractChecker.java:

O AbstractChecker.java facilita a implementação de um Checker. Por exemplo ele já implementa ignore(ruleId) e resetIgnore(), e também getRulesDefinition().

O método isCheckRule(ruleId) deve ser usado na sua implementação do método check(Sentence) para verificar se determinada regra deve ser aplicada ou não. Outros métodos auxiliares são createExample(..) e createMistake(..).

Atenção: Você deve declarar todas as regras implementadas pelo Checker usando o método add(RuleDefinition) do AbstractChecker.java. Dessa forma você o método getRulesDefinition() saberá quais regras estão implementadas.

RuleDefinition e Mistake

Você pode usar a implementação JavaRuleDefition.java para criar instâncias de RuleDefinition. Se estiver usando AbstractChecker.java você deve cadastrar os RuleDefinition usando o método add(..).
No AbstractChecker.java é possível usar o método createMistake(..) para criar uma Mistake mais facilmente passando um RuleDefinition. Caso esteja implementando Checker.java direto use MistakeImpl.java.

Exemplo

Veja uma implementação exemplo aqui: SpaceChecker.java
Este Checker procura erros simples no uso de símbolo de pontuação usando expressões regulares. Encontra erros como:

Este programa é  bom.
Este programa é bom .
Este programa é ( era) bom.
Este programa é era bom.Mas agora é melhor.

Configurar o arquivo rules.properties

Você pode declarar os novos Checkers no arquivo rules.properties. Basta anexar o nome da classe na propriedade checkers, separando por virgula:

# ---------------------------- CHECKER COMPOSITE -------------------------------
# comma separated checkers
checkers=br.usp.pcs.lta.cogroo.tools.checker.rules.applier.RulesApplier,br.usp.pcs.lta.cogroo.tools.checker.checkers.SpaceChecker

Dessa forma seu novo Checker será iniciado junto com o resto do corretor.

Código envolvido:

Checker.java - source:cogroo3/trunk/CoGrOOBase/src/main/java/br/usp/pcs/lta/cogroo/tools/checker/Checker.java
AbstractChecker.java - source:cogroo3/trunk/CoGrOOBase/src/main/java/br/usp/pcs/lta/cogroo/tools/checker/AbstractChecker.java
rules.properties - source:cogroo3/trunk/CoGrOOBase/src/main/resources/br/usp/pcs/lta/cogroo/tools/checker/rules/rules.properties
rules.xml - source:cogroo3/trunk/CoGrOOBase/src/main/rules/rules.xml
SpaceChecker.java - source:cogroo3/trunk/CoGrOOBase/src/main/java/br/usp/pcs/lta/cogroo/tools/checker/checkers/SpaceChecker.java
JavaRuleDefinition - source:cogroo3/trunk/CoGrOOBase/src/main/java/br/usp/pcs/lta/cogroo/tools/checker/JavaRuleDefinition.java
MistakeImpl.java - source:cogroo3/trunk/CoGrOOBase/src/main/java/br/usp/pcs/lta/cogroo/entity/impl/runtime/MistakeImpl.java