Commit aeaf47b8 by Steven Bird

reworking import statements to avoid wildcard imports; making nltk.sem.util…

reworking import statements to avoid wildcard imports; making nltk.sem.util depend on fewer external modules
parent 3fc4c2b6
......@@ -328,7 +328,7 @@ def printCCGTree(lwidth,tree):
### Demonstration code
# Construct the lexicon
lex = lexicon.parseLexicon('''
lex = parseLexicon('''
:- S, NP, N, VP # Primitive categories, S is the target primitive
Det :: NP/N # Family of words
......
......@@ -5,7 +5,10 @@
# URL: <http://www.nltk.org/>
# For license information, see LICENSE.TXT
from nltk.ccg.api import ParserI, FunctionalCategory
from nltk.parse import ParserI
from nltk.internals import Counter
from nltk.ccg.api import FunctionalCategory
class UndirectedBinaryCombinator(object):
"""
......
......@@ -16,11 +16,8 @@ except ImportError:
warnings.warn("nltk.draw package not loaded "
"(please install Tkinter library).")
else:
from cfg import *
from tree import *
from cfg import ProductionList, CFGEditor, CFGDemo
from tree import (TreeSegmentWidget, tree_to_treesegment,
TreeWidget, TreeView, draw_trees)
from dispersion import dispersion_plot
# Make sure that nltk.draw.cfg and nltk.draw.tree refer to the correct
# modules (and not to nltk.cfg & nltk.tree)
import cfg, tree
from table import Table
......@@ -11,9 +11,6 @@
Visualization tools for CFGs.
"""
import re
"""
Idea for a nice demo:
- 3 panes: grammar, treelet, working area
......@@ -53,12 +50,18 @@ Operations:
- if connected to top & bottom, then disconnect
"""
from nltk.grammar import ContextFreeGrammar, Nonterminal, parse_cfg_production
from nltk.tree import Tree
import re
from util import *
from tree import *
from Tkinter import (Button, Canvas, ColorizedList,
Entry, Frame, IntVar, Label, Scrollbar,
ShowText, SymbolWidget, Text, TextWidget,
Tk, Toplevel)
from nltk.grammar import (ContextFreeGrammar, parse_cfg_production,
Nonterminal, nonterminals)
from nltk.tree import Tree
from nltk.draw.tree import TreeSegmentWidget, tree_to_treesegment
form nltk.draw.util import CanvasFrame
######################################################################
# Production List
......@@ -585,7 +588,6 @@ class CFGDemo(object):
# The leaves of the tree.
leaves = []
for word in self._text:
if isinstance(word, Token): word = word.type()
leaves.append(TextWidget(c, word, font=leaf_font, draggable=1))
# Put it all together into one tree
......
......@@ -11,9 +11,11 @@
Tkinter widgets for displaying multi-column listboxes and tables.
"""
from util import *
import operator
from Tkinter import (Frame, Label, Listbox, Scrollbar, Tk)
######################################################################
# Multi-Column Listbox
######################################################################
......@@ -84,7 +86,7 @@ class MultiListbox(Frame):
include_labels = True
if len(columns) == 0:
raise ValuError("Expected at least one column")
raise ValueError("Expected at least one column")
# Instance variables
self._column_names = tuple(columns)
......
......@@ -13,9 +13,13 @@ Graphically display a Tree.
import sys
from nltk.tree import Tree
from Tkinter import (BoxWidget, CanvasFrame, IntVar,
Menu, OvalWidget, ParenWidget, TextWidget, Tk,
canvas)
from util import *
from nltk.util import in_idle
from nltk.tree import Tree
from nltk.draw.util import CanvasWidget
##//////////////////////////////////////////////////////
## Tree Segment
......
......@@ -36,7 +36,10 @@ homepage<http://www.ags.uni-sb.de/~konrad/clig.html>}.
"""
from Tkinter import *
from Tkinter import (Button, Canvas, Entry, Frame, Label, Menu, Menubutton,
RAISED, Scrollbar, StringVar, Text, Tk, Toplevel,
Widget, value)
import tkFont, tkMessageBox, tkFileDialog
from nltk.util import in_idle
......
......@@ -6,13 +6,14 @@
# URL: <http://www.nltk.org>
# For license information, see LICENSE.TXT
import operator
from collections import defaultdict
from nltk.sem.util import skolemize
from nltk.sem import skolemize
from nltk.sem.logic import (VariableExpression, EqualityExpression,
ApplicationExpression, LogicParser,
NegatedExpression, Variable,
AndExpression, unique_variable, operator)
AndExpression, unique_variable)
from nltk.inference.api import Prover, BaseProverCommand
......
......@@ -6,6 +6,8 @@
# URL: <http://www.nltk.org/>
# For license information, see LICENSE.TXT
from nltk.internals import Counter
from nltk.sem.logic import (VariableExpression, EqualityExpression,
ApplicationExpression, LogicParser,
AbstractVariableExpression, AllExpression,
......
......@@ -42,12 +42,12 @@ is then created with domain and valuation as parameters.
"""
from nltk.sem.util import (batch_parse, batch_interpret, batch_evaluate,
root_semrep, parse_valuation_line,
parse_valuation, parse_logic, skolemize)
root_semrep, parse_valuation)
from nltk.sem.evaluate import (Valuation, Assignment, Model, Undefined,
is_rel, set2rel, arity)
from nltk.sem.logic import (LogicParser, boolean_ops, binding_ops,
equality_preds)
equality_preds, parse_logic)
from nltk.sem.skolemize import skolemize
from nltk.sem.lfg import FStructure
from nltk.sem.relextract import extract_rels
from nltk.sem.boxer import Boxer
......
......@@ -8,13 +8,20 @@
# For license information, see LICENSE.TXT
import os
import re
import operator
import subprocess
from optparse import OptionParser
import tempfile
import nltk
from nltk.sem.logic import *
from nltk.sem.drt import *
from nltk.internals import Counter, find_binary
from nltk.sem.logic import (ExpectedMoreTokensException, ParseException,
UnexpectedTokenException, Variable)
from nltk.sem.drt import (DRS, DrtApplicationExpression, DrtEqualityExpression,
DrtNegatedExpression, DrtOrExpression, DrtParser,
DrtProposition, DrtTokens, DrtVariableExpression)
"""
An interface to Boxer.
......@@ -174,7 +181,7 @@ class Boxer(object):
return stdout
def _find_binary(self, name, bin_dir, verbose=False):
return nltk.internals.find_binary(name,
return find_binary(name,
path_to_bin=bin_dir,
env_vars=['CANDCHOME'],
url='http://svn.ask.it.usyd.edu.au/trac/candc/',
......
......@@ -6,7 +6,16 @@
# URL: <http://www.nltk.org/>
# For license information, see LICENSE.TXT
from logic import *
import operator
from nltk.sem.logic import (APP, AbstractVariableExpression, AllExpression,
AndExpression, ApplicationExpression, BinaryExpression,
BooleanExpression, ConstantExpression, EqualityExpression,
EventVariableExpression, ExistsExpression, Expression,
FunctionVariableExpression, ImpExpression,
IndividualVariableExpression, LambdaExpression, Tokens,
LogicParser, NegatedExpression, OrExpression, Variable,
is_eventvar, is_funcvar, is_indvar)
# Import Tkinter-based modules if they are available
try:
......
......@@ -9,12 +9,16 @@
from tkFont import Font
from nltk.draw import *
from Tkinter import (Button, Frame, IntVar, Label,
Listbox, Menu, Scrollbar, Tk)
from nltk.draw import CanvasFrame, ShowText
from nltk.util import in_idle
from nltk.tag import RegexpTagger
from nltk.parse.malt import MaltParser
from logic import Variable
from drt import DrsDrawer, DrtVariableExpression
from glue import DrtGlue
from nltk.parse import MaltParser
from nltk.sem.logic import Variable
from nltk.sem.drt import DrsDrawer, DrtVariableExpression
from nltk.sem.glue import DrtGlue
class DrtGlueDemo(object):
def __init__(self, examples):
......
......@@ -19,9 +19,16 @@ models.
from pprint import pformat
import inspect
import textwrap
from nltk.decorators import decorator
from logic import *
from nltk.sem.logic import (AbstractVariableExpression, AllExpression,
AndExpression, ApplicationExpression, EqualityExpression,
ExistsExpression, IffExpression, ImpExpression,
IndividualVariableExpression, LambdaExpression,
LogicParser, NegatedExpression, OrExpression,
Variable, is_indvar)
class Error(Exception): pass
......
......@@ -10,10 +10,10 @@ import os
import nltk
from nltk.internals import Counter
from nltk.parse import *
from nltk.corpus import brown
from nltk.tag import UnigramTagger, BigramTagger, TrigramTagger, RegexpTagger
import logic
from nltk.sem.logic import (LogicParser, Expression, Variable, VariableExpression,
LambdaExpression, AbstractVariableExpression)
import drt
import linearlogic
......@@ -32,8 +32,8 @@ class GlueFormula(object):
indices = set()
if isinstance(meaning, str):
self.meaning = logic.LogicParser().parse(meaning)
elif isinstance(meaning, logic.Expression):
self.meaning = LogicParser().parse(meaning)
elif isinstance(meaning, Expression):
self.meaning = meaning
else:
raise RuntimeError, 'Meaning term neither string or expression: %s, %s' % (meaning, meaning.__class__)
......@@ -65,21 +65,21 @@ class GlueFormula(object):
arg_meaning_abstracted = arg.meaning
if return_indices:
for dep in self.glue.simplify().antecedent.dependencies[::-1]: # if self.glue is (A -o B), dep is in A.dependencies
arg_meaning_abstracted = self.make_LambdaExpression(logic.Variable('v%s' % dep),
arg_meaning_abstracted = self.make_LambdaExpression(Variable('v%s' % dep),
arg_meaning_abstracted)
return_meaning = self.meaning.applyto(arg_meaning_abstracted)
return self.__class__(return_meaning, return_glue, return_indices)
def make_VariableExpression(self, name):
return logic.VariableExpression(name)
return VariableExpression(name)
def make_LambdaExpression(self, variable, term):
return logic.LambdaExpression(variable, term)
return LambdaExpression(variable, term)
def lambda_abstract(self, other):
assert isinstance(other, GlueFormula)
assert isinstance(other.meaning, logic.AbstractVariableExpression)
assert isinstance(other.meaning, AbstractVariableExpression)
return self.__class__(self.make_LambdaExpression(other.meaning.variable,
self.meaning),
linearlogic.ImpExpression(other.glue, self.glue))
......
......@@ -9,8 +9,10 @@
from nltk.parse import load_parser
from nltk.draw.tree import draw_trees
from util import skolemize
from nltk.sem import logic
from nltk.sem.skolemize import skolemize
from nltk.sem.logic import (AllExpression, AndExpression, ApplicationExpression,
ExistsExpression, IffExpression, ImpExpression,
LambdaExpression, NegatedExpression, OrExpression)
"""
An implementation of the Hole Semantics model, following Blackburn and Bos,
......@@ -46,14 +48,14 @@ class Constants(object):
HOLE = 'HOLE'
LABEL = 'LABEL'
MAP = {ALL: lambda v,e: logic.AllExpression(v.variable, e),
EXISTS: lambda v,e: logic.ExistsExpression(v.variable, e),
NOT: logic.NegatedExpression,
AND: logic.AndExpression,
OR: logic.OrExpression,
IMP: logic.ImpExpression,
IFF: logic.IffExpression,
PRED: logic.ApplicationExpression}
MAP = {ALL: lambda v,e: AllExpression(v.variable, e),
EXISTS: lambda v,e: ExistsExpression(v.variable, e),
NOT: NegatedExpression,
AND: AndExpression,
OR: OrExpression,
IMP: ImpExpression,
IFF: IffExpression,
PRED: ApplicationExpression}
class HoleSemantics(object):
"""
......@@ -65,7 +67,7 @@ class HoleSemantics(object):
"""
def __init__(self, usr):
"""
Constructor. `usr' is a C{logic.sem.Expression} representing an
Constructor. `usr' is a C{sem.Expression} representing an
Underspecified Representation Structure (USR). A USR has the following
special predicates:
ALL(l,v,n),
......@@ -101,10 +103,10 @@ class HoleSemantics(object):
Extract holes, labels, formula fragments and constraints from the hole
semantics underspecified representation (USR).
"""
if isinstance(usr, logic.AndExpression):
if isinstance(usr, AndExpression):
self._break_down(usr.first)
self._break_down(usr.second)
elif isinstance(usr, logic.ApplicationExpression):
elif isinstance(usr, ApplicationExpression):
func, args = usr.uncurry()
if func.variable.name == Constants.LEQ:
self.constraints.add(Constraint(args[0], args[1]))
......@@ -320,7 +322,7 @@ def hole_readings(sentence, grammar_filename=None, verbose=False):
if verbose: print 'Raw: ', sem
# Skolemize away all quantifiers. All variables become unique.
while isinstance(sem, logic.LambdaExpression):
while isinstance(sem, LambdaExpression):
sem = sem.term
skolemized = skolemize(sem)
......
......@@ -1660,6 +1660,31 @@ class LogicParser(object):
return '<' + self.__class__.__name__ + ': ' + msg + '>'
def parse_logic(s, logic_parser=None):
"""
Convert a file of First Order Formulas into a list of {Expression}s.
:param s: the contents of the file
:type s: str
:param logic_parser: The parser to be used to parse the logical expression
:type logic_parser: C{LogicParser}
:return: a list of parsed formulas.
:rtype: list of L{Expression}
"""
if logic_parser is None:
logic_parser = LogicParser()
statements = []
for linenum, line in enumerate(s.splitlines()):
line = line.strip()
if line.startswith('#') or line=='': continue
try:
statements.append(logic_parser.parse(line))
except ParseException:
raise ValueError, 'Unable to parse line %s: %s' % (linenum, line)
return statements
class StringTrie(defaultdict):
LEAF = "<leaf>"
......
# Natural Language Toolkit: Semantic Interpretation
#
# Author: Ewan Klein <ewan@inf.ed.ac.uk>
#
# Copyright (C) 2001-2011 NLTK Project
# URL: <http://www.nltk.org/>
# For license information, see LICENSE.TXT
from nltk.sem.logic import (AllExpression, AndExpression, ApplicationExpression,
EqualityExpression, ExistsExpression, IffExpression,
ImpExpression, NegatedExpression, OrExpression,
VariableExpression, skolem_function)
def skolemize(expression, univ_scope=None, used_variables=None):
"""
Skolemize the expression and convert to conjunctive normal form (CNF)
"""
if univ_scope is None:
univ_scope = set()
if used_variables is None:
used_variables = set()
if isinstance(expression, AllExpression):
term = skolemize(expression.term, univ_scope|set([expression.variable]), used_variables|set([expression.variable]))
return term.replace(expression.variable, VariableExpression(unique_variable(ignore=used_variables)))
elif isinstance(expression, AndExpression):
return skolemize(expression.first, univ_scope, used_variables) &\
skolemize(expression.second, univ_scope, used_variables)
elif isinstance(expression, OrExpression):
return to_cnf(skolemize(expression.first, univ_scope, used_variables),
skolemize(expression.second, univ_scope, used_variables))
elif isinstance(expression, ImpExpression):
return to_cnf(skolemize(-expression.first, univ_scope, used_variables),
skolemize(expression.second, univ_scope, used_variables))
elif isinstance(expression, IffExpression):
return to_cnf(skolemize(-expression.first, univ_scope, used_variables),
skolemize(expression.second, univ_scope, used_variables)) &\
to_cnf(skolemize(expression.first, univ_scope, used_variables),
skolemize(-expression.second, univ_scope, used_variables))
elif isinstance(expression, EqualityExpression):
return expression
elif isinstance(expression, NegatedExpression):
negated = expression.term
if isinstance(negated, AllExpression):
term = skolemize(-negated.term, univ_scope, used_variables|set([negated.variable]))
if univ_scope:
return term.replace(negated.variable, skolem_function(univ_scope))
else:
skolem_constant = VariableExpression(unique_variable(ignore=used_variables))
return term.replace(negated.variable, skolem_constant)
elif isinstance(negated, AndExpression):
return to_cnf(skolemize(-negated.first, univ_scope, used_variables),
skolemize(-negated.second, univ_scope, used_variables))
elif isinstance(negated, OrExpression):
return skolemize(-negated.first, univ_scope, used_variables) &\
skolemize(-negated.second, univ_scope, used_variables)
elif isinstance(negated, ImpExpression):
return skolemize(negated.first, univ_scope, used_variables) &\
skolemize(-negated.second, univ_scope, used_variables)
elif isinstance(negated, IffExpression):
return to_cnf(skolemize(-negated.first, univ_scope, used_variables),
skolemize(-negated.second, univ_scope, used_variables)) &\
to_cnf(skolemize(negated.first, univ_scope, used_variables),
skolemize(negated.second, univ_scope, used_variables))
elif isinstance(negated, EqualityExpression):
return expression
elif isinstance(negated, NegatedExpression):
return skolemize(negated.term, univ_scope, used_variables)
elif isinstance(negated, ExistsExpression):
term = skolemize(-negated.term, univ_scope|set([negated.variable]), used_variables|set([negated.variable]))
return term.replace(negated.variable, VariableExpression(unique_variable(ignore=used_variables)))
elif isinstance(negated, ApplicationExpression):
return expression
else:
raise Exception('\'%s\' cannot be skolemized' % expression)
elif isinstance(expression, ExistsExpression):
term = skolemize(expression.term, univ_scope, used_variables|set([expression.variable]))
if univ_scope:
return term.replace(expression.variable, skolem_function(univ_scope))
else:
skolem_constant = VariableExpression(unique_variable(ignore=used_variables))
return term.replace(expression.variable, skolem_constant)
elif isinstance(expression, ApplicationExpression):
return expression
else:
raise Exception('\'%s\' cannot be skolemized' % expression)
def to_cnf(first, second):
"""
Convert this split disjunction to conjunctive normal form (CNF)
"""
if isinstance(first, AndExpression):
r_first = to_cnf(first.first, second)
r_second = to_cnf(first.second, second)
return r_first & r_second
elif isinstance(second, AndExpression):
r_first = to_cnf(first, second.first)
r_second = to_cnf(first, second.second)
return r_first & r_second
else:
return first | second
......@@ -15,9 +15,7 @@ a first-order model.
import evaluate
import re
import nltk
from nltk.sem.logic import *
##############################################################
## Utility functions for connecting parse output to semantics
......@@ -33,10 +31,15 @@ def batch_parse(inputs, grammar, trace=0):
:rtype: dict
:return: a mapping from input sentences to a list of L{Tree}s
"""
if isinstance(grammar, nltk.grammar.FeatureGrammar):
cp = nltk.parse.FeatureChartParser(grammar)
# put imports here to avoid circult dependencies
from nltk.grammar import FeatureGrammar
from nltk.parse import FeatureChartParser, load_parser
if isinstance(grammar, FeatureGrammar):
cp = FeatureChartParser(grammar)
else:
cp = nltk.parse.load_parser(grammar, trace=trace)
cp = load_parser(grammar, trace=trace)
parses = []
for sent in inputs:
tokens = sent.split() # use a tokenizer?
......@@ -53,8 +56,10 @@ def root_semrep(syntree, semkey='SEM'):
:return: the semantic representation at the root of a L{Tree}
:rtype: L{logic.Expression}
"""
from nltk.grammar import FeatStructNonterminal
node = syntree.node
assert isinstance(node, nltk.grammar.FeatStructNonterminal)
assert isinstance(node, FeatStructNonterminal)
try:
return node[semkey]
except KeyError:
......@@ -152,120 +157,6 @@ def parse_valuation(s):
val = evaluate.Valuation(statements)
return val
def parse_logic(s, logic_parser=None):
"""
Convert a file of First Order Formulas into a list of {Expression}s.
:param s: the contents of the file
:type s: str
:param logic_parser: The parser to be used to parse the logical expression
:type logic_parser: C{LogicParser}
:return: a list of parsed formulas.
:rtype: list of L{Expression}
"""
if logic_parser is None:
logic_parser = LogicParser()
statements = []
for linenum, line in enumerate(s.splitlines()):
line = line.strip()
if line.startswith('#') or line=='': continue
try:
statements.append(logic_parser.parse(line))
except ParseException:
raise ValueError, 'Unable to parse line %s: %s' % (linenum, line)
return statements
def skolemize(expression, univ_scope=None, used_variables=None):
"""
Skolemize the expression and convert to conjunctive normal form (CNF)
"""
if univ_scope is None:
univ_scope = set()
if used_variables is None:
used_variables = set()
if isinstance(expression, AllExpression):
term = skolemize(expression.term, univ_scope|set([expression.variable]), used_variables|set([expression.variable]))
return term.replace(expression.variable, VariableExpression(unique_variable(ignore=used_variables)))
elif isinstance(expression, AndExpression):
return skolemize(expression.first, univ_scope, used_variables) &\
skolemize(expression.second, univ_scope, used_variables)
elif isinstance(expression, OrExpression):
return to_cnf(skolemize(expression.first, univ_scope, used_variables),
skolemize(expression.second, univ_scope, used_variables))
elif isinstance(expression, ImpExpression):
return to_cnf(skolemize(-expression.first, univ_scope, used_variables),
skolemize(expression.second, univ_scope, used_variables))
elif isinstance(expression, IffExpression):
return to_cnf(skolemize(-expression.first, univ_scope, used_variables),
skolemize(expression.second, univ_scope, used_variables)) &\
to_cnf(skolemize(expression.first, univ_scope, used_variables),
skolemize(-expression.second, univ_scope, used_variables))
elif isinstance(expression, EqualityExpression):
return expression
elif isinstance(expression, NegatedExpression):
negated = expression.term
if isinstance(negated, AllExpression):
term = skolemize(-negated.term, univ_scope, used_variables|set([negated.variable]))
if univ_scope:
return term.replace(negated.variable, skolem_function(univ_scope))
else:
skolem_constant = VariableExpression(unique_variable(ignore=used_variables))
return term.replace(negated.variable, skolem_constant)
elif isinstance(negated, AndExpression):
return to_cnf(skolemize(-negated.first, univ_scope, used_variables),
skolemize(-negated.second, univ_scope, used_variables))
elif isinstance(negated, OrExpression):
return skolemize(-negated.first, univ_scope, used_variables) &\
skolemize(-negated.second, univ_scope, used_variables)
elif isinstance(negated, ImpExpression):
return skolemize(negated.first, univ_scope, used_variables) &\
skolemize(-negated.second, univ_scope, used_variables)
elif isinstance(negated, IffExpression):
return to_cnf(skolemize(-negated.first, univ_scope, used_variables),
skolemize(-negated.second, univ_scope, used_variables)) &\
to_cnf(skolemize(negated.first, univ_scope, used_variables),
skolemize(negated.second, univ_scope, used_variables))
elif isinstance(negated, EqualityExpression):
return expression
elif isinstance(negated, NegatedExpression):
return skolemize(negated.term, univ_scope, used_variables)
elif isinstance(negated, ExistsExpression):
term = skolemize(-negated.term, univ_scope|set([negated.variable]), used_variables|set([negated.variable]))
return term.replace(negated.variable, VariableExpression(unique_variable(ignore=used_variables)))
elif isinstance(negated, ApplicationExpression):
return expression
else:
raise Exception('\'%s\' cannot be skolemized' % expression)
elif isinstance(expression, ExistsExpression):
term = skolemize(expression.term, univ_scope, used_variables|set([expression.variable]))
if univ_scope:
return term.replace(expression.variable, skolem_function(univ_scope))
else:
skolem_constant = VariableExpression(unique_variable(ignore=used_variables))
return term.replace(expression.variable, skolem_constant)
elif isinstance(expression, ApplicationExpression):
return expression
else:
raise Exception('\'%s\' cannot be skolemized' % expression)
def to_cnf(first, second):
"""
Convert this split disjunction to conjunctive normal form (CNF)
"""
if isinstance(first, AndExpression):
r_first = to_cnf(first.first, second)
r_second = to_cnf(first.second, second)
return r_first & r_second
elif isinstance(second, AndExpression):
r_first = to_cnf(first, second.first)
r_second = to_cnf(first, second.second)
return r_first & r_second
else:
return first | second
def demo_model0():
global m0, g0
......@@ -311,7 +202,9 @@ def demo_legacy_grammar():
Define 'test.fcfg' to be the following
"""
g = nltk.parse_fcfg("""
from nltk.grammar import parse_fcfg
g = parse_fcfg("""
% start S
S[sem=<hello>] -> 'hello'
""")
......
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