Commit cb2d0a75 by Steven Bird

Modified Linear Logic module to support fromstring-style initialisation, cf…

Modified Linear Logic module to support fromstring-style initialisation, cf https://github.com/nltk/nltk/issues/656
parent 984f5240
...@@ -53,7 +53,6 @@ from nltk.sem.lfg import FStructure ...@@ -53,7 +53,6 @@ from nltk.sem.lfg import FStructure
from nltk.sem.relextract import (extract_rels, rtuple, clause) from nltk.sem.relextract import (extract_rels, rtuple, clause)
from nltk.sem.boxer import Boxer from nltk.sem.boxer import Boxer
from nltk.sem.drt import DrtExpression, DRS from nltk.sem.drt import DrtExpression, DRS
from nltk.sem.linearlogic import LinearLogicParser
# from nltk.sem.glue import Glue # from nltk.sem.glue import Glue
# from nltk.sem.hole import HoleSemantics # from nltk.sem.hole import HoleSemantics
......
...@@ -13,8 +13,72 @@ from nltk.sem.logic import _LogicParser, APP ...@@ -13,8 +13,72 @@ from nltk.sem.logic import _LogicParser, APP
_counter = Counter() _counter = Counter()
class Tokens(object):
#Punctuation
OPEN = '('
CLOSE = ')'
#Operations
IMP = '-o'
PUNCT = [OPEN, CLOSE]
TOKENS = PUNCT + [IMP]
class _LinearLogicParser(_LogicParser):
"""A linear logic expression parser."""
def __init__(self):
_LogicParser.__init__(self)
self.operator_precedence = {APP: 1, Tokens.IMP: 2, None: 3}
self.right_associated_operations += [Tokens.IMP]
def get_all_symbols(self):
return Tokens.TOKENS
def handle(self, tok, context):
if tok not in Tokens.TOKENS:
return self.handle_variable(tok, context)
elif tok == Tokens.OPEN:
return self.handle_open(tok, context)
def get_BooleanExpression_factory(self, tok):
if tok == Tokens.IMP:
return ImpExpression
else:
return None
def make_BooleanExpression(self, factory, first, second):
return factory(first, second)
def attempt_ApplicationExpression(self, expression, context):
"""Attempt to make an application expression. If the next tokens
are an argument in parens, then the argument expression is a
function being applied to the arguments. Otherwise, return the
argument expression."""
if self.has_priority(APP, context):
if self.inRange(0) and self.token(0) == Tokens.OPEN:
self.token() #swallow then open paren
argument = self.parse_Expression(APP)
self.assertNextToken(Tokens.CLOSE)
expression = ApplicationExpression(expression, argument, None)
return expression
def make_VariableExpression(self, name):
if name[0].isupper():
return VariableExpression(name)
else:
return ConstantExpression(name)
@python_2_unicode_compatible @python_2_unicode_compatible
class Expression(object): class Expression(object):
_linear_logic_parser = _LinearLogicParser()
@classmethod
def fromstring(cls, s):
return cls._linear_logic_parser.parse(s)
def applyto(self, other, other_indices=None): def applyto(self, other, other_indices=None):
return ApplicationExpression(self, other, other_indices) return ApplicationExpression(self, other, other_indices)
...@@ -368,74 +432,17 @@ class LinearLogicApplicationException(Exception): ...@@ -368,74 +432,17 @@ class LinearLogicApplicationException(Exception):
pass pass
class Tokens(object):
#Punctuation
OPEN = '('
CLOSE = ')'
#Operations
IMP = '-o'
PUNCT = [OPEN, CLOSE]
TOKENS = PUNCT + [IMP]
class LinearLogicParser(_LogicParser):
"""A linear logic expression parser."""
def __init__(self):
_LogicParser.__init__(self)
self.operator_precedence = {APP: 1, Tokens.IMP: 2, None: 3}
self.right_associated_operations += [Tokens.IMP]
def get_all_symbols(self):
return Tokens.TOKENS
def handle(self, tok, context):
if tok not in Tokens.TOKENS:
return self.handle_variable(tok, context)
elif tok == Tokens.OPEN:
return self.handle_open(tok, context)
def get_BooleanExpression_factory(self, tok):
if tok == Tokens.IMP:
return ImpExpression
else:
return None
def make_BooleanExpression(self, factory, first, second):
return factory(first, second)
def attempt_ApplicationExpression(self, expression, context):
"""Attempt to make an application expression. If the next tokens
are an argument in parens, then the argument expression is a
function being applied to the arguments. Otherwise, return the
argument expression."""
if self.has_priority(APP, context):
if self.inRange(0) and self.token(0) == Tokens.OPEN:
self.token() #swallow then open paren
argument = self.parse_Expression(APP)
self.assertNextToken(Tokens.CLOSE)
expression = ApplicationExpression(expression, argument, None)
return expression
def make_VariableExpression(self, name):
if name[0].isupper():
return VariableExpression(name)
else:
return ConstantExpression(name)
def demo(): def demo():
llp = LinearLogicParser() lexpr = Expression.fromstring
print(llp.parse(r'f')) print(lexpr(r'f'))
print(llp.parse(r'(g -o f)')) print(lexpr(r'(g -o f)'))
print(llp.parse(r'((g -o G) -o G)')) print(lexpr(r'((g -o G) -o G)'))
print(llp.parse(r'g -o h -o f')) print(lexpr(r'g -o h -o f'))
print(llp.parse(r'(g -o f)(g)').simplify()) print(lexpr(r'(g -o f)(g)').simplify())
print(llp.parse(r'(H -o f)(g)').simplify()) print(lexpr(r'(H -o f)(g)').simplify())
print(llp.parse(r'((g -o G) -o G)((g -o f))').simplify()) print(lexpr(r'((g -o G) -o G)((g -o f))').simplify())
print(llp.parse(r'(H -o H)((g -o f))').simplify()) print(lexpr(r'(H -o H)((g -o f))').simplify())
if __name__ == '__main__': if __name__ == '__main__':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment