Versão 5.12.5
O analisador gramática de Link exibe a estrutura linguística (linguagem natural) dos subconjuntos ingleses, tailandeses, russos, árabes, persas e limitados de meia dúzia de outros idiomas. Essa estrutura é um gráfico de links digitados (bordas) entre as palavras em uma frase. Pode -se obter as analistas mais convencionais de HPSG (constituinte) e estilo de dependência da gramática do link, aplicando uma coleção de regras para se converter a esses diferentes formatos. Isso é possível porque a gramática do link é um pouco "mais profunda" na estrutura "sintacto-semântica" de uma frase: fornece informações consideravelmente mais finas e detalhadas do que o que é comumente disponível nos analisadores convencionais.
A teoria da análise gramatical Link foi originalmente desenvolvida em 1991 por Davy Temperley, John Lafferty e Daniel Sleator, na época em que professores de lingüística e ciência da computação na Universidade Carnegie Mellon. As três publicações iniciais sobre essa teoria fornecem a melhor introdução e visão geral; Desde então, houve centenas de publicações explorando ainda mais, examinando e estendendo as idéias.
Embora com base na base de código Carnegie-Mellon original, o pacote gramatical atual evoluiu drasticamente e é profundamente diferente das versões anteriores. Houve inúmeras correções de bugs; O desempenho melhorou por várias ordens de magnitude. O pacote é totalmente multithread, totalmente ativado UTF-8 e foi lavado para segurança, permitindo a implantação da nuvem. A cobertura de análise do inglês foi dramaticamente melhorada; Outras línguas foram adicionadas (principalmente, tailandês e russo). Há uma série de novos recursos, incluindo suporte para morfologia, dialetos e um sistema de peso fino (custo), permitindo um comportamento do tipo vetorial. Há um novo e sofisticado tokenizer adaptado para morfologia: pode oferecer divisões alternativas para palavras morfologicamente ambíguas. Os dicionários podem ser atualizados em tempo de execução, permitindo que os sistemas que realizem aprendizado contínuo da gramática também analisem ao mesmo tempo. Ou seja, as atualizações do dicionário e a análise são mutuamente seguras de threads. Classes de palavras podem ser reconhecidas com regexes. A análise do gráfico planar aleatório é totalmente suportado; Isso permite amostragem uniforme do espaço dos gráficos planares. Um relatório detalhado do que mudou pode ser encontrado no Changelog.
Este código é lançado sob a licença LGPL, disponibilizando -o gratuitamente para uso privado e comercial, com poucas restrições. Os termos da licença são fornecidos no arquivo de licença incluído neste software.
Consulte a página principal da web para obter mais informações. Esta versão é uma continuação do analisador CMU original.
A partir da versão 5.9.0, o sistema inclui um sistema experimental para gerar frases. Eles são especificados usando uma API "Preencher os espaços em branco", onde as palavras são substituídas em locais de curingas, sempre que o resultado é uma frase gramaticalmente válida. Detalhes adicionais estão na página do homem: man link-generator (no subdiretório do man ).
Este gerador é usado no projeto OpenCog Language Learning, que tem como objetivo aprender automaticamente vincular as gramáticas do Corpora, usando técnicas teóricas de informações novas e inovadoras, um pouco semelhantes às encontradas nas redes neurais artificiais (aprendizado profundo), mas usando representações explicitamente simbólicas.
O analisador inclui as APIs em várias linguagens de programação diferentes, bem como uma ferramenta útil da linha de comando para brincar com ela. Aqui está alguma saída típica:
linkparser> This is a test!
Linkage 1, cost vector = (UNUSED=0 DIS= 0.00 LEN=6)
+-------------Xp------------+
+----->WV----->+---Ost--+ |
+---Wd---+-Ss*b+ +Ds**c+ |
| | | | | |
LEFT-WALL this.p is.v a test.n !
(S (NP this.p) (VP is.v (NP a test.n)) !)
LEFT-WALL 0.000 Wd+ hWV+ Xp+
this.p 0.000 Wd- Ss*b+
is.v 0.000 Ss- dWV- O*t+
a 0.000 Ds**c+
test.n 0.000 Ds**c- Os-
! 0.000 Xp- RW+
RIGHT-WALL 0.000 RW-
Esta tela bastante ocupada ilustra muitas coisas interessantes. Por exemplo, o link Ss*b conecta o verbo e o sujeito e indica que o sujeito é singular. Da mesma forma, o link Ost conecta o verbo e o objeto e também indica que o objeto é singular. O link WV (WV-Wall) aponta para o verbo da cabeça da frase, enquanto o link Wd aponta para o substantivo da cabeça. O link Xp se conecta à pontuação à direita. O link Ds**c conecta o substantivo ao determinante: confirma novamente que o substantivo é singular e também que o substantivo começa com uma consoante. (O link PH , não é necessário aqui, é usado para forçar o acordo fonético, distinguindo 'a' de 'an'). Esses tipos de link estão documentados na documentação do link em inglês.
A parte inferior da tela é uma listagem dos "disjuntos" usados para cada palavra. Os disjunços são simplesmente uma lista dos conectores empregados para formar os links. Eles são particularmente interessantes porque servem como uma forma extremamente fina de uma "parte da fala". Assim, por exemplo: o S- O+ disjuntista indica um verbo transitivo: é um verbo que leva um sujeito e um objeto. A marcação adicional acima indica que 'is' não está sendo usado apenas como um verbo transitivo, mas também indica detalhes mais finos: um verbo transitivo que levou um sujeito singular e foi usado (é utilizável como) o verbo da cabeça de uma frase. O valor do ponto flutuante é o "custo" do disjunto; Ele captura muito aproximadamente a idéia da probabilidade de log desse uso gramatical específico. Por mais que as partes da fala se estejam se correlacionam com as médias de palavras, também os peças de fala de grãos finos se correlacionam com distinções e gradações de significado muito mais finas.
O analisador-gramática de link também suporta análises morfológicas. Aqui está um exemplo em russo:
linkparser> это теста
Linkage 1, cost vector = (UNUSED=0 DIS= 0.00 LEN=4)
+-----MVAip-----+
+---Wd---+ +-LLCAG-+
| | | |
LEFT-WALL это.msi тест.= =а.ndnpi
O link LL conecta o caule 'те' ao sufixo 'а'. O link MVA se conecta apenas ao sufixo, porque, em russo, são os sufixos que carregam toda a estrutura sintática, e não os caules. O lexis russo está documentado aqui.
O dicionário tailandês agora está totalmente desenvolvido, cobrindo efetivamente todo o idioma. Um exemplo em tailandês:
linkparser> นายกรัฐมนตรี ขึ้น กล่าว สุนทรพจน์
Linkage 1, cost vector = (UNUSED=0 DIS= 2.00 LEN=2)
+---------LWs--------+
| +<---S<--+--VS-+-->O-->+
| | | | |
LEFT-WALL นายกรัฐมนตรี.n ขึ้น.v กล่าว.v สุนทรพจน์.n
O link VS conecta dois verbos '' 'e' '' 'em uma construção de verbo em série. Um resumo dos tipos de link está documentado aqui. A documentação completa da gramática da Tailândia pode ser encontrada aqui.
A gramática de link tailandesa também aceita entradas marcadas com POS e com nome de entrada. Cada palavra pode ser anotada com a tag POS do link. Por exemplo:
linkparser> เมื่อวานนี้.n มี.ve คน.n มา.x ติดต่อ.v คุณ.pr ครับ.pt
Found 1 linkage (1 had no P.P. violations)
Unique linkage, cost vector = (UNUSED=0 DIS= 0.00 LEN=12)
+---------------------PT--------------------+
+---------LWs---------+---------->VE---------->+ |
| +<---S<---+-->O-->+ +<--AXw<-+--->O--->+ |
| | | | | | | |
LEFT-WALL เมื่อวานนี้.n[!] มี.ve[!] คน.n[!] มา.x[!] ติดต่อ.v[!] คุณ.pr[!] ครับ.pt[!]
A documentação completa para o dicionário tailandês pode ser encontrada aqui.
O dicionário tailandês aceita tagsets LST20 para POS e entidades nomeadas, para preencher a lacuna entre as ferramentas fundamentais da PNL e o analisador de link. Por exemplo:
linkparser> linkparser> วันที่_25_ธันวาคม@DTM ของ@PS ทุก@AJ ปี@NN เป็น@VV วัน@NN คริสต์มาส@NN
Found 348 linkages (348 had no P.P. violations)
Linkage 1, cost vector = (UNUSED=0 DIS= 1.00 LEN=10)
+--------------------------------LWs--------------------------------+
| +<------------------------S<------------------------+
| | +---------->PO--------->+ |
| +----->AJpr----->+ +<---AJj<--+ +---->O---->+------NZ-----+
| | | | | | | |
LEFT-WALL วันที่_25_ธันวาคม@DTM[!] ของ@PS[!].pnn ทุก@AJ[!].jl ปี@NN[!].n เป็น@VV[!].v วัน@NN[!].na คริสต์มาส@NN[!].n
Observe que cada palavra acima é anotada com tags POS LST20 e tags NE. A documentação completa para as tags POS do link e os tagsets LST20 pode ser encontrada aqui. Mais informações sobre o LST20, por exemplo, diretrizes de anotação e estatísticas de dados, podem ser encontradas aqui.
O any suporta gráficos planares aleatórios uniformemente amostrados:
linkparser> asdf qwer tyuiop fghj bbb
Found 1162 linkages (1162 had no P.P. violations)
+-------ANY------+-------ANY------+
+---ANY--+--ANY--+ +---ANY--+--ANY--+
| | | | | |
LEFT-WALL asdf[!] qwer[!] tyuiop[!] fghj[!] bbb[!]
A linguagem ady da mesma forma, realizando divisões morfológicas aleatórias:
linkparser> asdf qwerty fghjbbb
Found 1512 linkages (1512 had no P.P. violations)
+------------------ANY-----------------+
+-----ANY----+-------ANY------+ +---------LL--------+
| | | | |
LEFT-WALL asdf[!ANY-WORD] qwerty[!ANY-WORD] fgh[!SIMPLE-STEM].= =jbbb[!SIMPLE-SUFF]
Uma visão geral prolongada e um resumo podem ser encontrados na página da Wikipedia da Gramática Link, que aborda a maior parte da importação, aspectos primários da teoria. No entanto, não substitui os artigos originais publicados sobre o assunto:
Existem muitos outros documentos e referências listadas no site da Grammar Primary Link
Veja também a documentação da API C/C ++. As ligações para outras linguagens de programação, incluindo Python3, Java e Node.js, podem ser encontradas no diretório de ligações. (Existem dois conjuntos de ligações JavaScript: um conjunto para a API da biblioteca e outro conjunto para o analisador da linha de comando.)
| Contente | Descrição |
|---|---|
| LICENÇA | A licença descrevendo os termos de uso |
| Changelog | Um compêndio de mudanças recentes. |
| configure | O script de configuração GNU |
| Autogen.sh | Ferramenta de manutenção de configuração do desenvolvedor |
| link-grammar/*. c | O programa. (Escrito em ANSI-C) |
| ---- | ---- |
| encadernas/autoit/ | Ligações opcionais de idioma automático. |
| ligações/java/ | Ligações de idiomas Java opcionais. |
| ligações/js/ | Ligações opcionais de linguagem JavaScript. |
| ligações/lisp/ | Ligações de linguagem lisp comuns opcionais. |
| Bindings/Node.js/ | Node opcional.js Langues Ligatings. |
| encadeamentos/ocaml/ | Ligações opcionais de idiomas OCAML. |
| ligações/python/ | Ligações opcionais do idioma python3. |
| Bindings/Python-Examples/ | Link-Grammar Test Suite e Python Language Ligating Usage Exemplo. |
| encadernas/swig/ | Arquivo de interface SWIG, para outras interfaces de FFI. |
| encadernas/vala/ | Cadeiras opcionais da linguagem Vala. |
| ---- | ---- |
| dados/en// | Dicionários de inglês. |
| dados/en/4.0.dict | O arquivo que contém as definições de dicionário. |
| dados/en/4.0.knowledge | O arquivo de conhecimento pós-processamento. |
| dados/en/4.0.constitUents | O arquivo de conhecimento constituinte. |
| dados/en/4.0.affix | O arquivo Afixo (prefixo/sufixo). |
| dados/en/4.0.regex | Adivinhador de morfologia baseado em expressão regular. |
| dados/en/tiny.dict | Um pequeno exemplo de dicionário. |
| dados/pt/words/ | Um diretório cheio de listas de palavras. |
| dados/en/corpus*.batch | Exemplo Corpora usada para teste. |
| ---- | ---- |
| dados/ru/ | Um dicionário russo de pleno direito |
| dados/th/ | Um dicionário tailandês de pleno direito (mais de 100.000 palavras) |
| dados/ar/ | Um dicionário árabe bastante completo |
| dados/fa/ | Um dicionário persa (farsi) |
| dados/de/ | Um pequeno protótipo dicionário alemão |
| dados/lt/ | Um pequeno protótipo dicionário lituano |
| dados/id/ | Um pequeno protótipo dicionário indonésio |
| dados/vn/ | Um pequeno protótipo dicionário vietnamita |
| dados/ele/ | Um dicionário de hebraico experimental |
| dados/kz/ | Um dicionário experimental de cazaque |
| dados/tr/ | Um dicionário turco experimental |
| ---- | ---- |
| morfologia/ar/ | Um analisador de morfologia árabe |
| morfologia/fa/ | Um analisador de morfologia persa |
| ---- | ---- |
| depurar/ | Informações sobre a depuração da biblioteca |
| msvc/ | Arquivos do projeto Microsoft Visual-C |
| Mingw/ | Informações sobre o uso de Mingw sob MSYs ou Cygwin |
O sistema é distribuído usando o formato tar.gz convencional; Ele pode ser extraído usando o comando tar -zxf link-grammar.tar.gz
Um tarball da versão mais recente pode ser baixado de:
https://www.gnucash.org/link glammar/downloads/
Os arquivos foram assinados digitalmente para garantir que não houvesse corrupção do conjunto de dados durante o download e para ajudar a garantir que nenhuma alteração maliciosa fosse feita nos internos do código por terceiros. As assinaturas podem ser verificadas com o comando gpg:
gpg --verify link-grammar-5.12.5.tar.gz.asc
que deve gerar saída idêntica a (exceto para a data):
gpg: Signature made Thu 26 Apr 2012 12:45:31 PM CDT using RSA key ID E0C0651C
gpg: Good signature from "Linas Vepstas (Hexagon Architecture Patches) <[email protected]>"
gpg: aka "Linas Vepstas (LKML) <[email protected]>"
Como alternativa, as soma de verificação do MD5 podem ser verificadas. Eles não fornecem segurança criptográfica, mas podem detectar corrupção simples. Para verificar as folhas de verificação, emita md5sum -c MD5SUM na linha de comando.
As tags no git podem ser verificadas executando o seguinte:
gpg --recv-keys --keyserver keyserver.ubuntu.com EB6AA534E0C0651C
git tag -v link-grammar-5.10.5
Para compilar o programa Link-Grammar Shared Biblioteca e Demonstração, na linha de comando, digite:
./configure
make
make check
Para instalar, altere o usuário para "root" e diga
make install
ldconfig
Isso instalará a biblioteca liblink-grammar.so em /usr/local/lib , os arquivos de cabeçalho em /usr/local/include/link-grammar e os dicionários em /usr/local/share/link-grammar . A execução ldconfig reconstruirá o cache da biblioteca compartilhada. Para verificar se a instalação foi bem-sucedida, execute (como usuário sem raios)
make installcheck
A biblioteca Link-Grammar possui recursos opcionais que são ativados automaticamente se configure detectar determinadas bibliotecas. Essas bibliotecas são opcionais na maioria dos sistemas e, se o recurso adicionar for desejado, as bibliotecas correspondentes precisam ser instaladas antes de executar configure .
Os nomes dos pacotes da biblioteca podem variar em vários sistemas (consulte o Google, se necessário ...). Por exemplo, os nomes podem incluir -devel em vez de -dev , ou ficar sem ele. Os nomes da biblioteca podem estar sem o prefixo lib .
libsqlite3-dev (para dicionário apoiado por sqlite)libz1g-dev ou libz-devel (atualmente necessário para o minisat2 em pacote)libedit-dev (ver EditLine)libhunspell-dev ou libaspell-dev (e o dicionário inglês correspondente).libtre-dev ou libpcre2-dev (muito mais rápido que a implementação da LIBC Regex e necessária para a correção em FreeBSD e Cygwin).libpcre2-dev é fortemente recomendado. Ele deve ser usado em determinados sistemas (conforme especificado em suas seções de construção). Se libedit-dev estiver instalado, as teclas de seta poderão ser usadas para editar a entrada da ferramenta Link-Parser; As teclas de seta para cima e para baixo lembrarão de entradas anteriores. Você quer isso; Isso facilita muito o teste e a edição.
Duas versões das ligações Node.js estão incluídas. Uma versão envolve a biblioteca; O outro usa o EMSCRIPTEN para envolver a ferramenta de linha de comando. As ligações da biblioteca estão em bindings/node.js enquanto o invólucro EMScriptten está em bindings/js .
Estes são criados usando npm . Primeiro, você deve construir a biblioteca Core C. Então faça o seguinte:
cd bindings/node.js
npm install
npm run make
Isso criará as ligações da biblioteca e também executará um pequeno teste de unidade (que deve passar). Um exemplo pode ser encontrado em bindings/node.js/examples/simple.js .
Para o invólucro da linha de comando, faça o seguinte:
cd bindings/js
./install_emsdk.sh
./build_packages.sh
As ligações do Python3 são construídas por padrão, desde que os pacotes de desenvolvimento Python correspondentes sejam instalados. (As ligações do Python2 não são mais suportadas.)
Esses pacotes são:
python3-develpython3-dev Nota: Antes de emitir configure (veja abaixo), você deve validar que as versões Python necessárias podem ser chamadas usando seu PATH .
O uso das ligações do Python é opcional ; Você não precisa disso se não planeja usar o Link-Grammar com o Python. Se você gosta de desativar as ligações do Python, use:
./configure --disable-python-bindings
O módulo linkgrammar.py fornece uma interface de alto nível no Python. Os scripts de example.py e sentence-check.py fornecem uma demonstração e tests.py executa testes de unidade.
make install pythondir=/where/to/install Por padrão, os Makefile tentam construir as ligações Java. O uso das ligações Java é opcional ; Você não precisa disso se não planeja usar o Link-Grammar com Java. Você pode pular a construção das ligações Java, desativando a seguinte maneira:
./configure --disable-java-bindings
Se jni.h não for encontrado, ou se ant não for encontrado, as ligações Java não serão construídas.
Notas sobre como encontrar jni.h :
Algumas distribuições comuns de Java JVM (principalmente as do sol) colocam esse arquivo em locais incomuns, onde não pode ser encontrado automaticamente. Para remediar isso, verifique se a variável de ambiente JAVA_HOME está definida corretamente. O script de configuração procura jni.h em $JAVA_HOME/Headers e em $JAVA_HOME/include ; Ele também examina locais correspondentes para $JDK_HOME . Se jni.h ainda não puder ser encontrado, especifique o local com a variável CPPFLAGS : por exemplo,
export CPPFLAGS="-I/opt/jdk1.5/include/:/opt/jdk1.5/include/linux"
ou
export CPPFLAGS="-I/c/java/jdk1.6.0/include/ -I/c/java/jdk1.6.0/include/win32/"
Observe que o uso de /opt não é padrão e a maioria das ferramentas do sistema não conseguirá encontrar os pacotes instalados lá.
O alvo de instalação /usr/local pode ser superado usando a opção de configure --prefix ; Então, por exemplo:
./configure --prefix=/opt/link-grammar
Ao usar pkg-config (veja abaixo), os locais de instalação não padrão podem ser detectados automaticamente.
As opções de configuração adicionais são impressas por
./configure --help
O sistema foi testado e funciona bem em sistemas Linux de 32 e 64 bits, FreeBSD, MacOS, bem como nos sistemas do Microsoft Windows. Notas específicas dependentes da OS seguem.
Os usuários finais devem fazer o download do tarball (consulte a descompactação e a verificação da assinatura).
A versão atual do GitHub destina -se a desenvolvedores (incluindo qualquer pessoa que esteja disposta a fornecer uma correção, um novo recurso ou uma melhoria). A ponta do ramo principal é frequentemente instável e às vezes pode ter um código ruim, pois está em desenvolvimento. Ele também precisa de instalação de ferramentas de desenvolvimento que não são instaladas por padrão. Por esse motivo, o uso da versão do GitHub é desencorajado para usuários finais regulares.
Clone It: git clone https://github.com/opencog/link-grammar.git
Ou faça o download como um zip:
https://github.com/opencog/link-grammar/archive/master.zip
Ferramentas que podem precisar de instalação antes que você possa criar link-gramática:
make (a variante gmake pode ser necessária)
m4
gcc ou clang
autoconf
libtool
autoconf-archive
pkg-config (pode ser nomeado pkgconf ou pkgconfig )
pip3 (para as ligações do Python)
Opcional:
swig (para ligações de idiomas)
flex
Apache Ant (para ligações Java)
graphviz (se você deseja usar o recurso de exibição do graph de palavras)
A versão do GitHub não inclui um script configure . Para gerá -lo, use:
autogen.sh
Se você receber erros, certifique-se de instalar os pacotes de desenvolvimento listados acima e se a instalação do sistema está atualizada. Especialmente, a falta de autoconf ou autoconf-archive pode causar erros estranhos e enganosos.
Para obter mais informações sobre como proceder, continue na seção Criando o sistema e as seções relevantes após ele.
Para configurar o modo de depuração , use:
configure --enable-debug
Ele adiciona algum código de depuração de verificação e funções que podem imprimir várias estruturas de dados.
Um recurso que pode ser útil para a depuração é a exibição do graph de palavras. Está ativado por padrão. Para mais detalhes sobre esse recurso, consulte a exibição do graph de palavras.
A configuração atual possui um problema aparente de mistura de biblioteca C ++ padrão quando gcc é usado (uma correção é bem -vinda). No entanto, a prática comum no FreeBSD é compilar com clang e não tem esse problema. Além disso, os pacotes complementares são instalados em /usr/local .
Então, aqui está como configure deve ser invocada:
env LDFLAGS=-L/usr/local/lib CPPFLAGS=-I/usr/local/include
CC=clang CXX=clang++ configure
Observe que pcre2 é um pacote necessário, pois a implementação existente libc REGEX não possui o nível necessário de suporte regex.
Alguns pacotes têm nomes diferentes dos mencionados nas seções anteriores:
minisat (minisat2) pkgconf (pkg-config)
A gramática do link de vanila simples deve compilar e executar o Apple MacOS muito bem, conforme descrito acima. No momento, não há problemas relatados.
Se você não precisar das ligações Java, quase certamente deve configurar com:
./configure --disable-java-bindings
Se você deseja ligações Java, certifique -se de definir a variável de ambiente jdk_home para onde quer que <Headers/jni.h> esteja. Defina a variável java_home na localização do compilador Java. Verifique se você está instalado.
Se você deseja construir a partir do GitHub (consulte o edifício do repositório do GitHub), pode instalar as ferramentas listadas lá usando o homebrew.
Existem três maneiras diferentes pelas quais o Link-Grammar pode ser compilado no Windows. Uma maneira é usar o Cygwin, que fornece uma camada de compatibilidade do Linux para Windows. Outra maneira é usar o sistema MSVC. Uma terceira maneira é usar o sistema Mingw, que usa o conjunto de ferramentas GNU para compilar os programas do Windows. O código -fonte suporta sistemas Windows do Vista ON.
Atualmente, o Cygwin Way produz o melhor resultado, pois suporta edição de linha com conclusão e histórico de comandos e também suporta graph de palavras exibidas em Windows. (Atualmente, o Mingw não possui libedit , e a porta MSVC atualmente não suporta a conclusão e o histórico de comando e também a ortografia.
A maneira mais fácil de ter a gramática do link trabalhando no MS Windows é usar o Cygwin, um ambiente semelhante ao Linux para o Windows, possibilitando o software portada em execução em sistemas POSIX para Windows. Faça o download e instale o Cygwin.
Observe que a instalação do pacote pcre2 é necessária porque a implementação do LIBC Regex não é capaz o suficiente.
Para mais detalhes, consulte Mingw/ReadMe-cygwin.md.
Outra maneira de criar link-gramática é usar o Mingw, que usa o conjunto de ferramentas GNU para compilar programas compatíveis com POSIX para Windows. O uso do Mingw/MSYS2 é provavelmente a maneira mais fácil de obter ligações Java viáveis para Windows. Faça o download e instale Mingw/MSYS2 em msys2.org.
Observe que a instalação do pacote pcre2 é necessária porque a implementação do LIBC Regex não é capaz o suficiente.
Para mais detalhes, consulte Mingw/ReadMe-mingw64.md.
Os arquivos do projeto Microsoft Visual C/C ++ podem ser encontrados no diretório msvc . Para instruções, consulte o arquivo readme.md lá.
Para executar o programa emitir o comando (supondo que esteja no seu caminho):
link-parser [arguments]
Isso inicia o programa. O programa possui muitas variáveis e opções definidas pelo usuário. Estes podem ser exibidos entrando !var no prompt de link-parser. Entrar !help exibirá alguns comandos adicionais.
Os dicionários são organizados em diretórios cujo nome é o código de idioma de 2 letras. O programa Link-Parser procura um diretório de idiomas nessa ordem, diretamente ou em um diretório, nomes data :
/usr/local/share/link-grammar ).Se o link-parser não conseguir encontrar o dicionário desejado, use o nível de verbosidade 4 para depurar o problema; por exemplo:
link-parser ru -verbosity=4
Outros locais podem ser especificados na linha de comando; por exemplo:
link-parser ../path/to-my/modified/data/en
Ao acessar dicionários em locais fora do padrão, os nomes de arquivos padrão ainda são assumidos ( ou seja , 4.0.dict , 4.0.affix , etc. ).
Os dicionários russos estão em data/ru . Assim, o analisador russo pode ser iniciado como:
link-parser ru
Se você não fornecer um argumento para o Link-Parser, ele procura um idioma de acordo com a sua configuração atual de localidade. Se não conseguir encontrar um diretório de idiomas, o padrão é "EN".
Se você vir erros semelhantes a este:
Warning: The word "encyclop" found near line 252 of en/4.0.dict
matches the following words:
encyclop
This word will be ignored.
Em seguida, seus locais UTF-8 não estão instalados ou não configurados. O locale -a deve listar en_US.utf8 como um local. Caso contrário, você precisará dpkg-reconfigure locales e/ou executar update-locale ou possivelmente apt-get install locales , ou combinações ou variantes destes, dependendo do seu sistema operacional.
Existem várias maneiras de testar a construção resultante. Se as ligações do Python forem construídas, um programa de teste poderá ser encontrado no arquivo ./bindings/python-examples/tests.py executado, ele deve passar. Para mais detalhes, consulte ReadMe.md no diretório bindings/python-examples .
Também existem vários lotes de frases de teste/exemplo nos diretórios de dados do idioma, geralmente com os nomes corpus-*.batch do programa analisador pode ser executado no modo de lote, para testar o sistema em um grande número de frases. O comando a seguir executa o analisador em um arquivo chamado corpus-basic.batch ;
link-parser < corpus-basic.batch
A linha !batch perto do topo do corpus-Basic.Batch lança o modo de lote. Nesse modo, as frases rotuladas com uma inicial * devem ser rejeitadas e aquelas que não estão começando com A * devem ser aceitas. Este arquivo em lote relata alguns erros, assim como os arquivos corpus-biolg.batch e corpus-fixes.batch . O trabalho está em andamento para corrigi -las.
O arquivo corpus-fixes.batch contém muitos milhares de frases que foram corrigidas desde a versão 4.1 original do Link-Grammar. O corpus-biolg.batch contém frases de biologia/texto médico do projeto BIOLG. O corpus-voa.batch contém amostras da Voice of America; o corpus-failures.batch contém um grande número de falhas.
Os números a seguir estão sujeitos a alterações, mas, neste momento, o número de erros que se pode esperar observar em cada um desses arquivos é aproximadamente o seguinte:
en/corpus-basic.batch: 88 errors
en/corpus-fixes.batch: 371 errors
lt/corpus-basic.batch: 15 errors
ru/corpus-basic.batch: 47 errors
O diretório de ligações/Python contém um teste de unidade para as ligações do Python. Ele também realiza várias verificações básicas que enfatizam as bibliotecas de gramática do link.
Existe uma API (Application Program Interface) no analisador. Isso facilita incorporá -lo em seus próprios aplicativos. A API está documentada no site.
O arquivo FindLinkGrammar.cmake pode ser usado para testar e configurar compilação em ambientes de construção baseados em cmake.
Para facilitar a compilação e a ligação, a versão atual usa o sistema PKG-Config. Para determinar a localização dos arquivos do cabeçalho-gramática do link, digamos a localização das bibliotecas, digamos, pkg-config --cflags link-grammar pkg-config --libs link-grammar Assim, por exemplo, um makefile típico pode incluir os alvos:
.c.o:
cc -O2 -g -Wall -c $< `pkg-config --cflags link-grammar`
$(EXE): $(OBJS)
cc -g -o $@ $^ `pkg-config --libs link-grammar`
Esta versão fornece arquivos Java que oferecem três maneiras de acessar o analisador. A maneira mais simples é usar a classe org.linkgrammar.linkgrammar; Isso fornece uma API Java muito simples para o analisador.
A segunda possibilidade é usar a classe LGService. Isso implementa um servidor de rede TCP/IP, fornecendo resultados de análise como mensagens JSON. Qualquer cliente compatível com JSON pode se conectar a este servidor e obter texto analisado.
A terceira possibilidade é usar a classe org.linkgrammar.lgremoteclient e, em particular, o método parse (). Esta classe é um cliente de rede que se conecta ao servidor JSON e converte a resposta de volta aos resultados acessíveis através da API ParseResult.
O código descrito acima será construído se o Apache ant estiver instalado.
O servidor de rede pode ser iniciado dizendo:
java -classpath linkgrammar.jar org.linkgrammar.LGService 9000
O acima é iniciado o servidor na porta 9000. A porta é omitida, o texto de ajuda é impresso. Este servidor pode ser contatado diretamente via TCP/IP; por exemplo:
telnet localhost 9000
(Alternadamente, use o NetCat em vez de telnet). Depois de conectar, digite:
text: this is an example sentence to parse
Os bytes devolvidos serão uma mensagem JSON, fornecendo as pastas da frase. Por padrão, a análise ASCII-ART do texto não é transmitida. Isso pode ser obtido enviando mensagens do formulário:
storeDiagramString:true, text: this is a test.
O analisador executará um verificador ortográfico em um estágio inicial, se encontrar uma palavra que não sabe e não pode adivinhar, com base na morfologia. O script de configuração procura os verificadores de aspell ou Hunspell; Se o ambiente do Aspell Devel for encontrado, o Aspell será usado, caso contrário, Hunspell será usado.
A adivinhação de feitiços pode ser desativada em tempo de execução, no cliente Link-Parser com o sinalizador !spell=0 . Digite !help para mais detalhes.
CUIDADO: Aspell versão 0.60.8 e possivelmente outros têm um vazamento de memória. O uso de adivinhação de feitiços em servidores de produção é fortemente desencorajado. Manter a adivinhação de feitiços desativados ( =0 ) em Parse_Options é segura.
É seguro usar o link-gramática em vários threads. Os tópicos podem compartilhar o mesmo dicionário. As opções de análise podem ser definidas por thread, com exceção da verbosidade, que é um global, compartilhado por todos os threads. É o único global.
Os determinantes fonéticos A/A antes de consoantes/vogais serem tratados por um novo tipo de link de pH, ligando o determinante à palavra imediatamente a seguir. Status: Introduzido na versão 5.1.0 (agosto de 2014). Feito principalmente, embora muitos substantivos de casos especiais estejam inacabados.
Os links direcionais são necessários para alguns idiomas, como idiomas lituanos, turcos e outros idiomas de ordem de palavra. O objetivo é ter um link indicar claramente qual palavra é a palavra da cabeça e qual é a dependente. Isso é conseguido pela pré -fixando conectores com uma única letra minúscula : H, D, indicando 'cabeça' e 'dependente'. As regras de ligação são tais que H corresponde nada ou D, e D corresponde a H ou nada. Este é um novo recurso na versão 5.1.0 (agosto de 2014). O site fornece documentação adicional.
Embora os links de link-gramática em inglês não sejam orientados, parece que uma direção de fato pode ser dada a eles que é completamente consistente com as concepções padrão de uma gramática de dependência.
As setas de dependência têm as seguintes propriedades:
Anti-reflexivo (uma palavra não pode depender de si mesma; não pode apontar para si mesma.)
Anti-simétrico (se o Word1 depende do Word2, então o Word2 não pode depender do Word1) (então, por exemplo, os determinantes dependem de substantivos, mas nunca vice-versa)
As setas não são transitivas, nem anti-transitivas: uma única palavra pode ser governada por várias cabeças. Por exemplo:
+------>WV------->+
+-->Wd-->+<--Ss<--+
| | |
LEFT-WALL she thinks.v
Ou seja, há um caminho para o sujeito, "ela", diretamente da parede esquerda, através do link WD, assim como indiretamente, da parede ao verbo raiz, e daí para o sujeito. Loops semelhantes formam -se com os links B e R. Tais loops são úteis para restringir o possível número de pastas: a restrição ocorre em conjunto com a meta-regra "sem links cruzados".
Existem várias noções matemáticas relacionadas, mas nenhuma captura LG direcional:
Os gráficos LG direcionais se assemelham a DAGs, exceto que a LG permite apenas uma parede (um elemento "superior").
Os gráficos LG direcionais se assemelham a ordens parciais estritas, exceto que as setas LG geralmente não são transitivas.
Os gráficos LG direcionais se assemelham a Catena, exceto que Catena são estritamente anti-transitivos-o caminho para qualquer palavra é único, em uma catena.
Os documentos fundamentais da LG exigem a planaridade dos gráficos de Parse. Isso se baseia em uma observação muito antiga de que as dependências quase nunca se cruzam nas línguas naturais: os humanos simplesmente não falam em frases onde os links cruzam. A imposição de restrições de planaridade fornece uma forte restrição de engenharia e algorítmica nas passas resultantes: o número total de pacotes a serem consideradas é fortemente reduzido e, portanto, a velocidade geral da análise pode ser bastante aumentada.
No entanto, existem exceções ocasionais e relativamente raras a essa regra de planaridade; Tais exceções são observadas em quase todos os idiomas. Várias dessas exceções são dadas para o inglês, abaixo.
Assim, parece importante relaxar a restrição de planaridade e encontrar outra coisa que seja quase tão rigorosa, mas ainda permite exceções pouco frequentes. Parece que o conceito de "transitividade marcante", conforme definido por Richard Hudson em sua teoria da "gramática da palavra" e depois defendida por Ben Goertzel, pode ser um mecanismo.
ftp://ftp.phon.ucl.ac.uk/pub/word-grammar/ell2-wg.pdf
http://www.phon.ucl.ac.uk/home/dick/enc/syntax.htm
http://goertzel.org/prowlgrammar.pdf
Na prática, a restrição de planaridade permite que algoritmos muito eficientes sejam usados na implementação do analisador. Assim, do ponto de vista da implementação, queremos manter a planaridade. Felizmente, existe uma maneira conveniente e inequívoca de ter nosso bolo e comê -lo também. Um diagrama não-planar pode ser desenhado em uma folha de papel usando a notação padrão de engenharia elétrica: um símbolo engraçado, onde quer que os fios cruzem. Essa notação é facilmente adaptada aos conectores LG; Abaixo está um exemplo de trabalho real, já implementado no atual dicionário LG English. Todas as passagens de link podem ser implementadas dessa maneira! Portanto, não precisamos realmente abandonar os algoritmos de análise atuais para obter diagramas não planares. Nós nem precisamos modificá -los! Hurra!
Aqui está um exemplo funcional: "Quero olhar e ouvir tudo". Isso quer dois links J apontando para 'tudo'. O diagrama desejado precisaria ficar assim:
+---->WV---->+
| +--------IV---------->+
| | +<-VJlpi--+
| | | +---xxx------------Js------->+
+--Wd--+-Sp*i+--TO-+-I*t-+-MVp+ +--VJrpi>+--MVp-+---Js->+
| | | | | | | | | |
LEFT-WALL I.p want.v to.r look.v at and.j-v listen.v to.r everything
O exposto acima realmente quer ter um link Js de 'em' para 'tudo', mas esse link Js cruza (confronta com - marcado por xxx) o link para a conjunção. Outros exemplos sugerem que se deve permitir que a maioria dos links atravesse as links para conjunções.
A planaridade que manipula a saída é dividir o link Js em dois: uma parte Jj e uma parte Jk ; Os dois são usados juntos para atravessar a conjunção. Atualmente, isso é implementado no dicionário inglês e funciona.
Essa articulação é de fato completamente genérica e pode ser estendida a qualquer tipo de cruzamento de links. Para que isso funcione, uma notação melhor seria conveniente; perhaps uJs- instead of Jj- and vJs- instead of Jk- , or something like that ... (TODO: invent better notation.) (NB: This is a kind of re-invention of "fat links", but in the dictionary, not in the code.)
Given that non-planar parses can be enabled without any changes to the parser algorithm, all that is required is to understand what sort of theory describes link-crossing in a coherent grounding. That theory is Dick Hudson's Landmark Transitivity, explained here.
This mechanism works as follows:
First, every link must be directional, with a head and a dependent. That is, we are concerned with directional-LG links, which are of the form x--A-->y or y<--A--x for words x,y and LG link type A.
Given either the directional-LG relation x--A-->y or y<--A--x, define the dependency relation x-->y. That is, ignore the link-type label.
Heads are landmarks for dependents. If the dependency relation x-->y holds, then x is said to be a landmark for y, and the predicate land(x,y) is true, while the predicate land(y,x) is false. Here, x and y are words, while --> is the landmark relation.
Although the basic directional-LG links form landmark relations, the total set of landmark relations is extended by transitive closure. That is, if land(x,y) and land(y,z) then land(x,z). That is, the basic directional-LG links are "generators" of landmarks; they generate by means of transitivity. Note that the transitive closure is unique.
In addition to the above landmark relation, there are two additional relations: the before and after landmark relations. (In English, these correspond to left and right; in Hebrew, the opposite). That is, since words come in chronological order in a sentence, the dependency relation can point either left or right. The previously-defined landmark relation only described the dependency order; we now introduce the word-sequence order. Thus, there are are land-before() and land-after() relations that capture both the dependency relation, and the word-order relation.
Notation: the before-landmark relation land-B(x,y) corresponds to x-->y (in English, reversed in right-left languages such as Hebrew), whereas the after-landmark relation land-A(x,y) corresponds to y<--x. That is, land(x,y) == land-B(x,y) or land-A(x,y) holds as a statement about the predicate form of the relations.
As before, the full set of directional landmarks are obtained by transitive closure applied to the directional-LG links. Two different rules are used to perform this closure:
-- land-B(x,y) and land(y,z) ==> land-B(x,y)
-- land-A(x,y) and land(y,z) ==> land-A(x,y)
Parsing is then performed by joining LG connectors in the usual manner, to form a directional link. The transitive closure of the directional landmarks are then computed. Finally, any parse that does not conclude with the "left wall" being the upper-most landmark is discarded.
Here is an example where landmark transitivity provides a natural solution to a (currently) broken parse. The "to.r" has a disjunct "I+ & MVi-" which allows "What is there to do?" to parse correctly. However, it also allows the incorrect parse "He is going to do". The fix would be to force "do" to take an object; however, a link from "do" to "what" is not allowed, because link-crossing would prevent it.
Fixing this requires only a fix to the dictionary, and not to the parser itself.
Examples where the no-links-cross constraint seems to be violated, in English:
"He is either in the 105th or the 106th battalion."
"He is in either the 105th or the 106th battalion."
Both seem to be acceptable in English, but the ambiguity of the "in-either" temporal ordering requires two different parse trees, if the no-links-cross rule is to be enforced. This seems un-natural. De forma similar:
"He is either here or he is there."
"He either is here or he is there."
A different example involves a crossing to the left wall. That is, the links LEFT-WALL--remains crosses over here--found :
"Here the remains can be found."
Other examples, per And Rosta:
The allowed--by link crosses cake--that :
He had been allowed to eat a cake by Sophy that she had made him specially
a--book , very--indeed
"a very much easier book indeed"
an--book , easy--to
"an easy book to read"
a--book , more--than
"a more difficult book than that one"
that--have crosses remains--of
"It was announced that remains have been found of the ark of the covenant"
There is a natural crossing, driven by conjunctions:
"I was in hell yesterday and heaven on Tuesday."
the "natural" linkage is to use MV links to connect "yesterday" and "on Tuesday" to the verb. However, if this is done, then these must cross the links from the conjunction "and" to "heaven" and "hell". This can be worked around partly as follows:
+-------->Ju--------->+
| +<------SJlp<----+
+<-SX<-+->Pp->+ +-->Mpn->+ +->SJru->+->Mp->+->Js->+
| | | | | | | | |
I was in hell yesterday and heaven on Tuesday
but the desired MV links from the verb to the time-prepositions "yesterday" and "on Tuesday" are missing -- whereas they are present, when the individual sentences "I was in hell yesterday" and "I was in heaven on Tuesday" are parsed. Using a conjunction should not wreck the relations that get used; but this requires link-crossing.
"Sophy wondered up to whose favorite number she should count"
Here, "up_to" must modify "number", and not "whose". There's no way to do this without link-crossing.
Link Grammar can be understood in the context of type theory. A simple introduction to type theory can be found in chapter 1 of the HoTT book. This book is freely available online and strongly recommended if you are interested in types.
Link types can be mapped to types that appear in categorial grammars. The nice thing about link-grammar is that the link types form a type system that is much easier to use and comprehend than that of categorial grammar, and yet can be directly converted to that system! That is, link-grammar is completely compatible with categorial grammar, and is easier-to-use. See the paper "Combinatory Categorial Grammar and Link Grammar are Equivalent" for details.
The foundational LG papers make comments to this effect; however, see also work by Bob Coecke on category theory and grammar. Coecke's diagrammatic approach is essentially identical to the diagrams given in the foundational LG papers; it becomes abundantly clear that the category theoretic approach is equivalent to Link Grammar. See, for example, this introductory sketch http://www.cs.ox.ac.uk/people/bob.coecke/NewScientist.pdf and observe how the diagrams are essentially identical to the LG jigsaw-puzzle piece diagrams of the foundational LG publications.
If you have any questions, please feel free to send a note to the mailing list.
The source code of link-parser and the link-grammar library is located at GitHub.
For bug reports, please open an issue there.
Although all messages should go to the mailing list, the current maintainers can be contacted at:
Linas Vepstas - <[email protected]>
Amir Plivatsky - <[email protected]>
Dom Lachowicz - <[email protected]>
A complete list of authors and copyright holders can be found in the AUTHORS file. The original authors of the Link Grammar parser are:
Daniel Sleator [email protected]
Computer Science Department 412-268-7563
Carnegie Mellon University www.cs.cmu.edu/~sleator
Pittsburgh, PA 15213
Davy Temperley [email protected]
Eastman School of Music 716-274-1557
26 Gibbs St. www.link.cs.cmu.edu/temperley
Rochester, NY 14604
John Lafferty [email protected]
Computer Science Department 412-268-6791
Carnegie Mellon University www.cs.cmu.edu/~lafferty
Pittsburgh, PA 15213
Some working notes.
Easy to fix: provide a more uniform API to the constituent tree. ie provide word index. Also, provide a better word API, showing word extent, subscript, etc.
There are subtle technical issues for handling capitalized first words. This needs to be fixed. In addition, for now these words are shown uncapitalized in the result linkages. This can be fixed.
Maybe capitalization could be handled in the same way that a/an could be handled! After all, it's essentially a nearest-neighbor phenomenon!
See also issue 690
The proximal issue is to add a cost, so that Bill gets a lower cost than bill.n when parsing "Bill went on a walk". The best solution would be to add a 'capitalization-mark token' during tokenization; this token precedes capitalized words. The dictionary then explicitly links to this token, with rules similar to the a/an phonetic distinction. The point here is that this moves capitalization out of ad-hoc C code and into the dictionary, where it can be handled like any other language feature. The tokenizer includes experimental code for that.
The old for parse ranking via corpus statistics needs to be revived. The issue can be illustrated with these example sentences:
"Please the customer, bring in the money"
"Please, turn off the lights"
In the first sentence, the comma acts as a conjunction of two directives (imperatives). In the second sentence, it is much too easy to mistake "please" for a verb, the comma for a conjunction, and come to the conclusion that one should please some unstated object, and then turn off the lights. (Perhaps one is pleasing by turning off the lights?)
When a sentence fails to parse, look for:
Poor agreement might be handled by giving a cost to mismatched lower-case connector letters.
An common phenomenon in English is that some words that one might expect to "properly" be present can disappear under various conditions. Below is a sampling of these. Some possible solutions are given below.
Expressions such as "Looks good" have an implicit "it" (also called a zero-it or phantom-it) in them; that is, the sentence should really parse as "(it) looks good". The dictionary could be simplified by admitting such phantom words explicitly, rather than modifying the grammar rules to allow such constructions. Other examples, with the phantom word in parenthesis, include:
This can extend to elided/unvoiced syllables:
Elided punctuation:
Normally, the subjects of imperatives must always be offset by a comma: "John, give me the hammer", but here, in muttering an oath, the comma is swallowed (unvoiced).
Some complex phantom constructions:
See also GitHub issue #224.
Actual ellipsis:
Here, the ellipsis stands for a subordinate clause, which attaches with not one, but two links: C+ & CV+ , and thus requires two words, not one. There is no way to have the ellipsis word to sink two connectors starting from the same word, and so some more complex mechanism is needed. The solution is to infer a second phantom ellipsis:
where the first ellipsis is a stand in for the subject of a subordinate clause, and the second stands in for an unknown verb.
Many (unstressed) syllables can be elided; in modern English, this occurs most commonly in the initial unstressed syllable:
Poorly punctuated sentences cause problems: for example:
"Mike was not first, nor was he last."
"Mike was not first nor was he last."
The one without the comma currently fails to parse. How can we deal with this in a simple, fast, elegant way? Similar questions for zero-copula and zero-that sentences.
Consider an argument between a professor and a dean, and the dean wants the professor to write a brilliant review. At the end of the argument, the dean exclaims: "I want the review brilliant!" This is a predicative adjective; clearly it means "I want the review [that you write to be] brilliant." However, taken out of context, such a construction is ungrammatical, as the predictiveness is not at all apparent, and it reads just as incorrectly as would "*Hey Joe, can you hand me that review brilliant?"
"Push button"
"Push button firmly"
The subject is a phantom; the subject is "you".
One possible solution is to perform a one-point compactification. The dictionary contains the phantom words, and their connectors. Ordinary disjuncts can link to these, but should do so using a special initial lower-case letter (say, 'z', in addition to 'h' and 'd' as is currently implemented). The parser, as it works, examines the initial letter of each connector: if it is 'z', then the usual pruning rules no longer apply, and one or more phantom words are selected out of the bucket of phantom words. (This bucket is kept out-of-line, it is not yet placed into sentence word sequence order, which is why the usual pruning rules get modified.) Otherwise, parsing continues as normal. At the end of parsing, if there are any phantom words that are linked, then all of the connectors on the disjunct must be satisfied (of course!) else the linkage is invalid. After parsing, the phantom words can be inserted into the sentence, with the location deduced from link lengths.
A more principled approach to fixing the phantom-word issue is to borrow the idea of re-writing from the theory of operator grammar. That is, certain phrases and constructions can be (should be) re-written into their "proper form", prior to parsing. The re-writing step would insert the missing words, then the parsing proceeds. One appeal of such an approach is that re-writing can also handle other "annoying" phenomena, such as typos (missing apostrophes, eg "lets" vs. "let's", "its" vs. "it's") as well as multi-word rewrites (eg "let's" vs. "let us", or "it's" vs. "it is").
Exactly how to implement this is unclear. However, it seems to open the door to more abstract, semantic analysis. Thus, for example, in Meaning-Text Theory (MTT), one must move between SSynt to DSynt structures. Such changes require a graph re-write from the surface syntax parse (eg provided by link-grammar) to the deep-syntactic structure. By contrast, handling phantom words by graph re-writing prior to parsing inverts the order of processing. This suggests that a more holistic approach is needed to graph rewriting: it must somehow be performed "during" parsing, so that parsing can both guide the insertion of the phantom words, and, simultaneously guide the deep syntactic rewrites.
Another interesting possibility arises with regards to tokenization. The current tokenizer is clever, in that it splits not only on whitespace, but can also strip off prefixes, suffixes, and perform certain limited kinds of morphological splitting. That is, it currently has the ability to re-write single-words into sequences of words. It currently does so in a conservative manner; the letters that compose a word are preserved, with a few exceptions, such as making spelling correction suggestions. The above considerations suggest that the boundary between tokenization and parsing needs to become both more fluid, and more tightly coupled.
Compare "she will be happier than before" to "she will be more happy than before." Current parser makes "happy" the head word, and "more" a modifier w/EA link. I believe the correct solution would be to make "more" the head (link it as a comparative), and make "happy" the dependent. This would harmonize rules for comparatives... and would eliminate/simplify rules for less,more.
However, this idea needs to be double-checked against, eg Hudson's word grammar. I'm confused on this issue ...
Currently, some links can act at "unlimited" length, while others can only be finite-length. eg determiners should be near the noun that they apply to. A better solution might be to employ a 'stretchiness' cost to some connectors: the longer they are, the higher the cost. (This eliminates the "unlimited_connector_set" in the dictionary).
Sometimes, the existence of one parse should suggest that another parse must surely be wrong: if one parse is possible, then the other parses must surely be unlikely. For example: the conjunction and.jg allows the "The Great Southern and Western Railroad" to be parsed as the single name of an entity. However, it also provides a pattern match for "John and Mike" as a single entity, which is almost certainly wrong. But "John and Mike" has an alternative parse, as a conventional-and -- a list of two people, and so the existence of this alternative (and correct) parse suggests that perhaps the entity-and is really very much the wrong parse. That is, the mere possibility of certain parses should strongly disfavor other possible parses. (Exception: Ben & Jerry's ice cream; however, in this case, we could recognize Ben & Jerry as the name of a proper brand; but this is outside of the "normal" dictionary (?) (but maybe should be in the dictionary!))
More examples: "high water" can have the connector A joining high.a and AN joining high.n; these two should either be collapsed into one, or one should be eliminated.
Use WordNet to reduce the number for parses for sentences containing compound verb phrases, such as "give up", "give off", etc.
To avoid a combinatorial explosion of parses, it would be nice to have an incremental parsing, phrase by phrase, using a sliding window algorithm to obtain the parse. Thus, for example, the parse of the last half of a long, run-on sentence should not be sensitive to the parse of the beginning of the sentence.
Doing so would help with combinatorial explosion. So, for example, if the first half of a sentence has 4 plausible parses, and the last half has 4 more, then currently, the parser reports 16 parses total. It would be much more useful if it could instead report the factored results: ie the four plausible parses for the first half, and the four plausible parses for the last half. This would ease the burden on downstream users of link-grammar.
This approach has at psychological support. Humans take long sentences and split them into smaller chunks that "hang together" as phrase- structures, viz compounded sentences. The most likely parse is the one where each of the quasi sub-sentences is parsed correctly.
This could be implemented by saving dangling right-going connectors into a parse context, and then, when another sentence fragment arrives, use that context in place of the left-wall.
This somewhat resembles the application of construction grammar ideas to the link-grammar dictionary. It also somewhat resembles Viterbi parsing to some fixed depth. Viz. do a full backward-forward parse for a phrase, and then, once this is done, take a Viterbi-step. That is, once the phrase is done, keep only the dangling connectors to the phrase, place a wall, and then step to the next part of the sentence.
Caution: watch out for garden-path sentences:
The horse raced past the barn fell.
The old man the boat.
The cotton clothing is made of grows in Mississippi.
The current parser parses these perfectly; a viterbi parser could trip on these.
Other benefits of a Viterbi decoder:
One may argue that Viterbi is a more natural, biological way of working with sequences. Some experimental, psychological support for this can be found at http://www.sciencedaily.com/releases/2012/09/120925143555.htm per Morten Christiansen, Cornell professor of psychology.
Consider the sentence "Thieves rob bank" -- a typical newspaper headline. LG currently fails to parse this, because the determiner is missing ("bank" is a count noun, not a mass noun, and thus requires a determiner. By contrast, "thieves rob water" parses just fine.) A fix for this would be to replace mandatory determiner links by (D- or {[[()]] & headline-flag}) which allows the D link to be omitted if the headline-flag bit is set. Here, "headline-flag" could be a new link-type, but one that is not subject to planarity constraints.
Note that this is easier said than done: if one simply adds a high-cost null link, and no headline-flag, then all sorts of ungrammatical sentences parse, with strange parses; while some grammatical sentences, which should parse, but currently don't, become parsable, but with crazy results.
More examples, from And Rosta:
"when boy meets girl"
"when bat strikes ball"
"both mother and baby are well"
A natural approach would be to replace fixed costs by formulas. This would allow the dialect/sociolect to be dynamically changeable. That is, rather than having a binary headline-flag, there would be a formula for the cost, which could be changed outside of the parsing loop. Such formulas could be used to enable/disable parsing specific to different dialects/sociolects, simply by altering the network of link costs.
A simpler alternative would be to have labeled costs (a cost vector), so that different dialects assign different costs to various links. A dialect would be specified during the parse, thus causing the costs for that dialect to be employed during parse ranking.
This has been implemented; what's missing is a practical tutorial on how this might be used.
A good reference for refining verb usage patterns is: "COBUILD GRAMMAR PATTERNS 1: VERBS from THE COBUILD SERIES", from THE BANK OF ENGLISH, HARPER COLLINS. Online at https://arts-ccr-002.bham.ac.uk/ccr/patgram/ and http://www.corpus.bham.ac.uk/publications/index.shtml
Currently tokenize.c tokenizes double-quotes and some UTF8 quotes (see the RPUNC/LPUNC class in en/4.0.affix - the QUOTES class is not used for that, but for capitalization support), with some very basic support in the English dictionary (see "% Quotation marks." there). However, it does not do this for the various "curly" UTF8 quotes, such as 'these' and “these”. This results is some ugly parsing for sentences containing such quotes. (Note that these are in 4.0.affix).
A mechanism is needed to disentangle the quoting from the quoted text, so that each can be parsed appropriately. It's somewhat unclear how to handle this within link-grammar. This is somewhat related to the problem of morphology (parsing words as if they were "mini-sentences",) idioms (phrases that are treated as if they were single words), set-phrase structures (if ... then ... not only... but also ...) which have a long-range structure similar to quoted text (he said ...).
See also GitHub issue #42.
"to be fishing": Link grammar offers four parses of "I was fishing for evidence", two of which are given low scores, and two are given high scores. Of the two with high scores, one parse is clearly bad. Its links "to be fishing.noun" as opposed to the correct "to be fishing.gerund". That is, I can be happy, healthy and wise, but I certainly cannot be fishing.noun. This is perhaps not just a bug in the structure of the dictionary, but is perhaps deeper: link-grammar has little or no concept of lexical units (ie collocations, idioms, institutional phrases), which thus allows parses with bad word-senses to sneak in.
The goal is to introduce more knowledge of lexical units into LG.
Different word senses can have different grammar rules (and thus, the links employed reveal the sense of the word): for example: "I tend to agree" vs. "I tend to the sheep" -- these employ two different meanings for the verb "tend", and the grammatical constructions allowed for one meaning are not the same as those allowed for the other. Yet, the link rules for "tend.v" have to accommodate both senses, thus making the rules rather complex. Worse, it potentially allows for non-sense constructions. If, instead, we allowed the dictionary to contain different rules for "tend.meaning1" and "tend.meaning2", the rules would simplify (at the cost of inflating the size of the dictionary).
Another example: "I fear so" -- the word "so" is only allowed with some, but not all, lexical senses of "fear". So eg "I fear so" is in the same semantic class as "I think so" or "I hope so", although other meanings of these verbs are otherwise quite different.
[Sin2004] "New evidence, new priorities, new attitudes" in J. Sinclair, (ed) (2004) How to use corpora in language teaching, Amsterdam: John Benjamins
See also: Pattern Grammar: A Corpus-Driven Approach to the Lexical Grammar of English
Susan Hunston and Gill Francis (University of Birmingham)
Amsterdam: John Benjamins (Studies in corpus linguistics, edited by Elena Tognini-Bonelli, volume 4), 2000
Book review.
“The Molecular Level of Lexical Semantics”, EA Nida, (1997) International Journal of Lexicography, 10(4): 265–274. On-line
The link-grammar provides several mechanisms to support circumpositions or even more complicated multi-word structures. One mechanism is by ordinary links; see the V, XJ and RJ links. The other mechanism is by means of post-processing rules. (For example, the "filler-it" SF rules use post-processing.) However, rules for many common forms have not yet been written. The general problem is of supporting structures that have "holes" in the middle, that require "lacing" to tie them together.
For a general theory, see catena.
For example, the adposition:
... from [xxx] on.
"He never said another word from then on."
"I promise to be quiet from now on."
"Keep going straight from that point on."
"We went straight from here on."
... from there on.
"We went straight, from the house on to the woods."
"We drove straight, from the hill onwards."
Note that multiple words can fit in the slot [xxx]. Note the tangling of another prepositional phrase: "... from [xxx] on to [yyy]"
More complicated collocations with holes include
"First.. next..."
"If ... then ..."
'Then' is optional ('then' is a 'null word'), for example:
"If it is raining, stay inside!"
"If it is raining, [then] stay inside!"
"if ... only ..." "If there were only more like you!"
"... not only, ... but also ..."
"As ..., so ..." "As it was commanded, so it shall be done"
"Either ... or ..."
"Both ... and ..." "Both June and Tom are coming"
"ought ... if ..." "That ought to be the case, if John is not lying"
"Someone ... who ..."
"Someone is outside who wants to see you"
"... for ... to ..."
"I need for you to come to my party"
The above are not currently supported. An example that is supported is the "non-referential it", eg
"It ... that ..."
"It seemed likely that John would go"
The above is supported by means of special disjuncts for 'it' and 'that', which must occur in the same post-processing domain.
See also:
http://www.phon.ucl.ac.uk/home/dick/enc2010/articles/extraposition.htm
http://www.phon.ucl.ac.uk/home/dick/enc2010/articles/relative-clause.htm
"...from X and from Y" "By X, and by Y, ..." Here, X and Y might be rather long phrases, containing other prepositions. In this case, the usual link-grammar linkage rules will typically conjoin "and from Y" to some preposition in X, instead of the correct link to "from X". Although adding a cost to keep the lengths of X and Y approximately equal can help, it would be even better to recognize the "...from ... and from..." pattern.
The correct solution for the "Either ... or ..." appears to be this:
---------------------------+---SJrs--+
+------???----------+ |
| +Ds**c+--SJls-+ +Ds**+
| | | | | |
either.r the lorry.n or.j-n the van.n
The wrong solution is
--------------------------+
+-----Dn-----+ +---SJrs---+
| +Ds**c+--SJn--+ +Ds**+
| | | | | |
neither.j the lorry.n nor.j-n the van.n
The problem with this is that "neither" must coordinate with "nor". That is, one cannot say "either.. nor..." "neither ... or ... " "neither ...and..." "but ... nor ..." The way I originally solved the coordination problem was to invent a new link called Dn, and a link SJn and to make sure that Dn could only connect to SJn, and nothing else. Thus, the lower-case "n" was used to propagate the coordination across two links. This demonstrates how powerful the link-grammar theory is: with proper subscripts, constraints can be propagated along links over large distances. However, this also makes the dictionary more complex, and the rules harder to write: coordination requires a lot of different links to be hooked together. And so I think that creating a single, new link, called ???, will make the coordination easy and direct. That is why I like that idea.
O ??? link should be the XJ link, which-see.
More idiomatic than the above examples: "...the chip on X's shoulder" "to do X a favour" "to give X a look"
The above are all examples of "set phrases" or "phrasemes", and are most commonly discussed in the context of MTT or Meaning-Text Theory of Igor Mel'cuk et al (search for "MTT Lexical Function" for more info). Mel'cuk treats set phrases as lexemes, and, for parsing, this is not directly relevant. However, insofar as phrasemes have a high mutual information content, they can dominate the syntactic structure of a sentence.
The current parse of "he wanted to look at and listen to everything." is inadequate: the link to "everything" needs to connect to "and", so that "listen to" and "look at" are treated as atomic verb phrases.
MTT suggests that perhaps the correct way to understand the contents of the post-processing rules is as an implementation of 'lexical functions' projected onto syntax. That is, the post-processing rules allow only certain syntactical constructions, and these are the kinds of constructions one typically sees in certain kinds of lexical functions.
Alternately, link-grammar suffers from a combinatoric explosion of possible parses of a given sentence. It would seem that lexical functions could be used to rule out many of these parses. On the other hand, the results are likely to be similar to that of statistical parse ranking (which presumably captures such quasi-idiomatic collocations at least weakly).
Ref. I. Mel'cuk: "Collocations and Lexical Functions", in ''Phraseology: theory, analysis, and applications'' Ed. Anthony Paul Cowie (1998) Oxford University Press pp. 23-54.
More generally, all of link-grammar could benefit from a MTT-izing of infrastructure.
Compare the above commentary on lexical functions to Hebrew morphological analysis. To quote Wikipedia:
This distinction between the word as a unit of speech and the root as a unit of meaning is even more important in the case of languages where roots have many different forms when used in actual words, as is the case in Semitic languages. In these, roots are formed by consonants alone, and different words (belonging to different parts of speech) are derived from the same root by inserting vowels. For example, in Hebrew, the root gdl represents the idea of largeness, and from it we have gadol and gdola (masculine and feminine forms of the adjective "big"), gadal "he grew", higdil "he magnified" and magdelet "magnifier", along with many other words such as godel "size" and migdal "tower".
Instead of hard-coding LL, declare which links are morpho links in the dict.
Version 6.0 will change Sentence to Sentence*, Linkage to Linkage* in the API. But perhaps this is a bad idea...