Esempio n. 1
0
def test():
	'''Some rudimentary test cases.'''
	from spanningtrees import spanning
	g1 = {'tokens': ['I', 'think', "I'm", 'a', 'wait', 'an', 'hour', 'or', '2', '&', 'THEN', 'tweet', '@sinittaofficial', '...'], 'node_edges': [['$a', 'W(tweet)', 'Conj'], ['$a', 'W(wait)', 'Conj'], ['$o', 'W(2)', 'Conj'], ['$o', 'W(hour)', 'Conj'], ["W(I'm)", '$a', None], ['W(hour)', 'W(an)', None], ['W(think)', "W(I'm)", None], ['W(think)', 'W(I)', None], ['W(tweet)', 'W(@sinittaofficial)', None], ['W(wait)', '$o', None]], 'nodes': ['$a', '$o', 'MW(&_THEN)', 'W(2)', 'W(@sinittaofficial)', "W(I'm)", 'W(I)', 'W(an)', 'W(hour)', 'W(think)', 'W(tweet)', 'W(wait)'], 'extra_node2words': {'$o': [['or', 'Coord']], '$a': [['&', 'Coord'], ['THEN', 'Coord']]}, 'node2words': {'W(@sinittaofficial)': ['@sinittaofficial'], "W(I'm)": ["I'm"], 'W(2)': ['2'], 'W(think)': ['think'], 'W(tweet)': ['tweet'], 'W(I)': ['I'], 'W(an)': ['an'], 'W(wait)': ['wait'], 'W(hour)': ['hour'], 'MW(&_THEN)': ['THEN', '&']}}
	g2 = {"tokens": ["@mandaffodil", "lol", ",", "we", "are", "one", ".", "and", "that", "was", "me", "this", "weekend", "especially", ".", "maybe", "put", "it", "off", "until", "you", "feel", "like", "~", "talking", "again", "?"], "node_edges": [["CBB1", "W(again)", "unspec"], ["CBB1", "W(feel)", "cbbhead"], ["CBB1", "W(you)", None], ["MW(put_off)", "W(it)", None], ["MW(put_off)", "W(until)", None], ["W($$)", "W(are)", None], ["W($$)", "W(lol)", None], ["W($$)", "W(maybe)", None], ["W($$)", "W(was)", None], ["W(are)", "W(one)", None], ["W(are)", "W(we)", None], ["W(feel)", "W(like)", None], ["W(like)", "W(talking)", None], ["W(maybe)", "MW(put_off)", None], ["W(until)", "CBB1", None], ["W(was)", "W(me)", None], ["W(was)", "W(that)", None], ["W(was)", "W(weekend)", None], ["W(weekend)", "W(especially)", None], ["W(weekend)", "W(this)", None]], "nodes": ["CBB1", "MW(put_off)", "W($$)", "W(again)", "W(are)", "W(especially)", "W(feel)", "W(it)", "W(like)", "W(lol)", "W(maybe)", "W(me)", "W(one)", "W(talking)", "W(that)", "W(this)", "W(until)", "W(was)", "W(we)", "W(weekend)", "W(you)"], "extra_node2words": {}, "node2words": {"W(are)": ["are"], "W(especially)": ["especially"], "W(like)": ["like"], "W(again)": ["again"], "W(that)": ["that"], "W(me)": ["me"], "W($$)": ["$$"], "W(maybe)": ["maybe"], "MW(put_off)": ["put", "off"], "W(was)": ["was"], "W(until)": ["until"], "W(you)": ["you"], "W(we)": ["we"], "W(feel)": ["feel"], "W(it)": ["it"], "W(talking)": ["talking"], "W(this)": ["this"], "W(one)": ["one"], "W(lol)": ["lol"], "W(weekend)": ["weekend"]}}
	g3 = {"tokens": ["A", "Top", "Quality", "Sandwich", "made", "to", "artistic", "standards", "."], "node_edges": [["CBB1", "W(A)", "unspec"], ["CBB1", "W(Quality)", "unspec"], ["CBB1", "W(Sandwich)", "cbbhead"], ["CBB1", "W(Top)", "unspec"], ["CBB2", "W(artistic)", "unspec"], ["CBB2", "W(standards)", "cbbhead"], ["W($$)", "CBB1", None], ["W(Sandwich)", "W(made)", None], ["W(made)", "W(to)", None], ["W(to)", "CBB2", None]], "nodes": ["CBB1", "CBB2", "W($$)", "W(A)", "W(Quality)", "W(Sandwich)", "W(Top)", "W(artistic)", "W(made)", "W(standards)", "W(to)"], "extra_node2words": {}, "node2words": {"W(made)": ["made"], "W(standards)": ["standards"], "W($$)": ["$$"], "W(to)": ["to"], "W(Top)": ["Top"], "W(artistic)": ["artistic"], "W(A)": ["A"], "W(Sandwich)": ["Sandwich"], "W(Quality)": ["Quality"]}}
	g4 = {"tokens": ["I~1", "wish", "I~2", "had", "you~1", "as", "my~1", "dentist~1", "early", "on", "in", "my~2", "life", "-", "maybe", "my~3", "teeth", "would", "have", "been", "a", "lot", "better", "then", "they", "are~1", "now~1", ",", "However", "I~3", "am", "glad", "you~2", "are~2", "my~4", "dentist~2", "now~2", "."], "node_edges": [["CBB1", "CBB2", "unspec"], ["CBB1", "W(as)", "unspec"], ["CBB1", "W(had)", "unspec"], ["CBB2", "W(early)", "cbbhead"], ["CBB2", "W(in)", "unspec"], ["CBB2", "W(life)", "unspec"], ["CBB2", "W(my~2)", "unspec"], ["CBB2", "W(on)", "unspec"], ["W($$)", "W(However)", None], ["W($$)", "W(am)", None], ["W($$)", "W(wish)", None], ["W($$)", "W(would)", None], ["W(am)", "W(glad)", None], ["W(are~1)", "W(been)", "Anaph"], ["W(are~1)", "W(now~1)", None], ["W(are~1)", "W(they)", None], ["W(as)", "W(my~1)", None], ["W(been)", "W(better)", None], ["W(better)", "MW(a_lot)", None], ["W(better)", "W(then)", None], ["W(glad)", "W(are~2)", None], ["W(had)", "W(I~2)", None], ["W(had)", "W(you~1)", None], ["W(have)", "W(been)", None], ["W(my~1)", "W(dentist~1)", None], ["W(teeth)", "W(my~3)", None], ["W(then)", "W(are~1)", None], ["W(wish)", "CBB1", None], ["W(would)", "W(have)", None], ["W(would)", "W(maybe)", None], ["W(would)", "W(teeth)", None]], "nodes": ["CBB1", "CBB2", "MW(a_lot)", "W($$)", "W(However)", "W(I~2)", "W(am)", "W(are~1)", "W(are~2)", "W(as)", "W(been)", "W(better)", "W(dentist~1)", "W(early)", "W(glad)", "W(had)", "W(have)", "W(in)", "W(life)", "W(maybe)", "W(my~1)", "W(my~2)", "W(my~3)", "W(now~1)", "W(on)", "W(teeth)", "W(then)", "W(they)", "W(wish)", "W(would)", "W(you~1)"], "extra_node2words": {}, "node2words": {"W(I~2)": ["I~2"], "W(However)": ["However"], "W(would)": ["would"], "W(then)": ["then"], "W(maybe)": ["maybe"], "W(my~2)": ["my~2"], "W(life)": ["life"], "W(are~1)": ["are~1"], "W(on)": ["on"], "W(as)": ["as"], "W(have)": ["have"], "W(my~3)": ["my~3"], "W(my~1)": ["my~1"], "W(they)": ["they"], "W(in)": ["in"], "W($$)": ["$$"], "W(wish)": ["wish"], "W(had)": ["had"], "W(you~1)": ["you~1"], "W(teeth)": ["teeth"], "W(are~2)": ["are~2"], "W(now~1)": ["now~1"], "W(better)": ["better"], "W(dentist~1)": ["dentist~1"], "MW(a_lot)": ["a", "lot"], "W(glad)": ["glad"], "W(am)": ["am"], "W(been)": ["been"], "W(early)": ["early"]}}
	g5 = {"tokens": ["I~1", "have~1", "purchased", "over", "15", "vehicles", "(", "cars", ",", "rvs", ",", "and~1", "boats", ")", "in", "my", "lifetime", "and~2", "I~2", "have~2", "to", "say", "the~1", "experience", "with", "Michael", "and~3", "Barrett", "Motor", "Cars", "of~1", "San", "Antonio", "was", "one", "of~2", "the~2", "best", "."], "node_edges": [["CBB1", "W(15)", "unspec"], ["CBB1", "W(I~1)", "unspec"], ["CBB1", "W(and~1)", "unspec"], ["CBB1", "W(boats)", "unspec"], ["CBB1", "W(cars)", "unspec"], ["CBB1", "W(have~1)", "cbbhead"], ["CBB1", "W(in)", "unspec"], ["CBB1", "W(lifetime)", "unspec"], ["CBB1", "W(my)", "unspec"], ["CBB1", "W(over)", "unspec"], ["CBB1", "W(purchased)", "unspec"], ["CBB1", "W(rvs)", "unspec"], ["CBB1", "W(vehicles)", "unspec"], ["CBB2", "W(Antonio)", "unspec"], ["CBB2", "W(Barrett)", "unspec"], ["CBB2", "W(Cars)", "unspec"], ["CBB2", "W(Michael)", "unspec"], ["CBB2", "W(Motor)", "unspec"], ["CBB2", "W(San)", "unspec"], ["CBB2", "W(and~3)", "unspec"], ["CBB2", "W(experience)", "unspec"], ["CBB2", "W(of~1)", "unspec"], ["CBB2", "W(the~1)", "unspec"], ["CBB2", "W(with)", "unspec"], ["CBB3", "W(best)", "unspec"], ["CBB3", "W(of~2)", "unspec"], ["CBB3", "W(one)", "unspec"], ["CBB3", "W(the~2)", "unspec"], ["MW(have~2_to)", "W(I~2)", None], ["MW(have~2_to)", "W(say)", None], ["W($$)", "CBB1", None], ["W($$)", "MW(have~2_to)", None], ["W($$)", "W(and~2)", None], ["W(say)", "W(was)", None], ["W(was)", "CBB2", None], ["W(was)", "CBB3", None]], "nodes": ["CBB1", "CBB2", "CBB3", "MW(have~2_to)", "W($$)", "W(15)", "W(Antonio)", "W(Barrett)", "W(Cars)", "W(I~1)", "W(I~2)", "W(Michael)", "W(Motor)", "W(San)", "W(and~1)", "W(and~2)", "W(and~3)", "W(best)", "W(boats)", "W(cars)", "W(experience)", "W(have~1)", "W(in)", "W(lifetime)", "W(my)", "W(of~1)", "W(of~2)", "W(one)", "W(over)", "W(purchased)", "W(rvs)", "W(say)", "W(the~1)", "W(the~2)", "W(vehicles)", "W(was)", "W(with)"], "extra_node2words": {}, "node2words": {"W(San)": ["San"], "W(I~2)": ["I~2"], "W(and~2)": ["and~2"], "W(the~2)": ["the~2"], "W(lifetime)": ["lifetime"], "W(say)": ["say"], "W(Barrett)": ["Barrett"], "W(purchased)": ["purchased"], "W(vehicles)": ["vehicles"], "W(15)": ["15"], "W(Cars)": ["Cars"], "W(experience)": ["experience"], "W(with)": ["with"], "W(over)": ["over"], "W(rvs)": ["rvs"], "W(my)": ["my"], "W(cars)": ["cars"], "W(in)": ["in"], "W(boats)": ["boats"], "W(I~1)": ["I~1"], "W(and~3)": ["and~3"], "W($$)": ["$$"], "W(the~1)": ["the~1"], "W(was)": ["was"], "W(and~1)": ["and~1"], "W(Motor)": ["Motor"], "W(of~1)": ["of~1"], "W(one)": ["one"], "W(have~1)": ["have~1"], "W(Antonio)": ["Antonio"], "MW(have~2_to)": ["to", "have~2"], "W(of~2)": ["of~2"], "W(best)": ["best"], "W(Michael)": ["Michael"]}}
	graphs = [g1,g2,g3,g4,g5][1:]	# skipping the first one for now, as it has coordination
	for g in graphs:
		f = FUDGGraph(g)
		upward(f)
		downward(f)
		for cbb in f.cbbnodes:
			print(cbb.name, cbb.topcandidates, cbb.parentcandidates)
		assert len({n.name for n in f.lexnodes})==len(f.lexnodes)
		for c in f.lexnodes:
			assert not c.isRoot
			#print(c, c.parentcandidates)
		stg = {(p.name,c.name) for c in f.lexnodes for p in c.parentcandidates}
		print(stg)
		print(spanning(stg, '$$'))
		print(len(spanning(stg, '$$')))
Esempio n. 2
0
def promcom(a, c, kirchhoff=False):
	stg = {(p.name,n.name) for n in a.lexnodes for p in n.parentcandidates}
	#stg = {(p.name,n.name) for n in a.nodes-{a.root} for ch in (n.topcandidates if n.isFE else {n.name}) for p in n.parentcandidates}
	assert any(1 for x,y in stg if x=='**'),('The root ** is not in the graph!',stg)

	if kirchhoff:	# approximate promiscuity: count spanning trees with matrix tree theorem (instead of enumerating them). an upper bound.
		prom = spanningtree(stg, '**')
		c['spanning trees'] = ValueStats(prom)
		if prom==0:
			raise Exception('No spanning trees for: '+repr(stg))
		c['promiscuity'] = ValueStats(prom)
		N = len(a.lexnodes)+1
		assert N>=2
		c['commitment'] = ValueStats(com(prom,N), show='mean')
		return

	def compatible_analyses(spanning_trees, nodeswithext):
		for analysis in spanning_trees:
			parmap = parentmap(analysis)
			#assert False,parmap
			violation = False

			# determine tops of all FEs in this analysis, going upward
			tops = {}
			for fe in sorted(a.fenodes, key=lambda node: node.height):
				assert fe.members,(fe,fe._pointerto)
				tops[fe.name] = min((tops.get(n.name,n.name) for n in fe.members), key=lambda v: depth(v,parmap))

			for fe in nodeswithext:
				top = tops[fe.name]
				for x in fe.externalchildren:
					if (parmap.get(x.name) or parmap[tops[x.name]])!=top:
						violation = True
						#if 'tix' in a.alltokens:
						#	assert False,(tops,x.name,parmap.get(x.name) or parmap[tops[x.name]],top,analysis)
						break
				if violation: break
			if not violation:
				yield analysis
	
	try:
		strees = spanning(stg, '**', threshold=10000)
		assert len(strees)>0
		c['spanning trees'] = ValueStats(len(strees))
		nodeswithext = {fe for fe in a.fenodes if fe.externalchildren}
		prom = sum(1 for t in compatible_analyses(strees, nodeswithext))
		assert prom>0,'No compatible trees for sentence: '+' '.join(a.alltokens)
		c['promiscuity'] = ValueStats(prom)
		N = len(a.lexnodes)+1
		assert N>=2
		c['commitment'] = ValueStats(com(prom,N), show='mean')
	except Exception as ex:
		if ex.message=='Too many spanning trees.':
			c['spanning tree overflow'] += 1
			c['spanning trees'] = ValueStats()	# prevents this from being counted (otherwise registers as 0)
			c['promiscuity'] = ValueStats()
			c['commitment'] = ValueStats()	# TODO: ??
		elif 'No compatible trees' in ex.message:
			raise
		else:
			raise Exception('No spanning trees for: '+repr(stg))
Esempio n. 3
0
def test():
    '''Some rudimentary test cases.'''
    from spanningtrees import spanning
    g1 = {
        'tokens': [
            'I', 'think', "I'm", 'a', 'wait', 'an', 'hour', 'or', '2', '&',
            'THEN', 'tweet', '@sinittaofficial', '...'
        ],
        'node_edges': [['$a', 'W(tweet)', 'Conj'], ['$a', 'W(wait)', 'Conj'],
                       ['$a', 'MW(&_THEN)', 'Coord'], ['$o', 'W(2)', 'Conj'],
                       ['$o', 'W(or)', 'Coord'], ['$o', 'W(hour)', 'Conj'],
                       ["W(I'm)", '$a', None], ['W(hour)', 'W(an)', None],
                       ['W(think)', "W(I'm)", None],
                       ['W(think)', 'W(I)', None],
                       ['W(tweet)', 'W(@sinittaofficial)', None],
                       ['W(wait)', '$o', None]],
        'nodes': [
            '$a', '$o', 'MW(&_THEN)', 'W(2)', 'W(@sinittaofficial)', "W(I'm)",
            'W(I)', 'W(an)', 'W(hour)', 'W(think)', 'W(tweet)', 'W(wait)',
            'W(or)'
        ],
        'varnodes': ['$o', '$a'],
        'coords': [['$o', ['W(2)', 'W(hour)'], ['W(or)']],
                   ['$a', ['W(tweet)', 'W(wait)'], ['MW(&_THEN)']]],
        'n2w': {
            'W(@sinittaofficial)': ['@sinittaofficial'],
            "W(I'm)": ["I'm"],
            'W(2)': ['2'],
            'W(think)': ['think'],
            'W(tweet)': ['tweet'],
            'W(I)': ['I'],
            'W(an)': ['an'],
            'W(wait)': ['wait'],
            'W(hour)': ['hour'],
            'MW(&_THEN)': ['THEN', '&'],
            'W(or)': ['or']
        }
    }
    g2 = {
        "tokens": [
            "@mandaffodil", "lol", ",", "we", "are", "one", ".", "and", "that",
            "was", "me", "this", "weekend", "especially", ".", "maybe", "put",
            "it", "off", "until", "you", "feel", "like", "~", "talking",
            "again", "?"
        ],
        "node_edges": [["FE1", "W(again)", "fe"], ["FE1", "W(feel)", "fe*"],
                       ["FE1", "W(you)", None], ["MW(put_off)", "W(it)", None],
                       ["MW(put_off)", "W(until)", None],
                       ["**", "W(are)", None], ["**", "W(lol)", None],
                       ["**", "W(maybe)", None], ["**", "W(was)", None],
                       ["W(are)", "W(one)", None], ["W(are)", "W(we)", None],
                       ["W(feel)", "W(like)", None],
                       ["W(like)", "W(talking)", None],
                       ["W(maybe)", "MW(put_off)", None],
                       ["W(until)", "FE1", None], ["W(was)", "W(me)", None],
                       ["W(was)", "W(that)", None],
                       ["W(was)", "W(weekend)", None],
                       ["W(weekend)", "W(especially)", None],
                       ["W(weekend)", "W(this)", None]],
        "nodes": [
            "FE1", "MW(put_off)", "**", "W(again)", "W(are)", "W(especially)",
            "W(feel)", "W(it)", "W(like)", "W(lol)", "W(maybe)", "W(me)",
            "W(one)", "W(talking)", "W(that)", "W(this)", "W(until)", "W(was)",
            "W(we)", "W(weekend)", "W(you)"
        ],
        "varnodes": [],
        "coords": [],
        "n2w": {
            "W(are)": ["are"],
            "W(especially)": ["especially"],
            "W(like)": ["like"],
            "W(again)": ["again"],
            "W(that)": ["that"],
            "W(me)": ["me"],
            "**": ["**"],
            "W(maybe)": ["maybe"],
            "MW(put_off)": ["put", "off"],
            "W(was)": ["was"],
            "W(until)": ["until"],
            "W(you)": ["you"],
            "W(we)": ["we"],
            "W(feel)": ["feel"],
            "W(it)": ["it"],
            "W(talking)": ["talking"],
            "W(this)": ["this"],
            "W(one)": ["one"],
            "W(lol)": ["lol"],
            "W(weekend)": ["weekend"]
        }
    }
    g3 = {
        "tokens": [
            "A", "Top", "Quality", "Sandwich", "made", "to", "artistic",
            "standards", "."
        ],
        "node_edges": [["FE1", "W(A)", "fe"], ["FE1", "W(Quality)", "fe"],
                       ["FE1", "W(Sandwich)", "fe*"], ["FE1", "W(Top)", "fe"],
                       ["FE2", "W(artistic)", "fe"],
                       ["FE2", "W(standards)", "fe*"], ["**", "FE1", None],
                       ["W(Sandwich)", "W(made)", None],
                       ["W(made)", "W(to)", None], ["W(to)", "FE2", None]],
        "nodes": [
            "FE1", "FE2", "**", "W(A)", "W(Quality)", "W(Sandwich)", "W(Top)",
            "W(artistic)", "W(made)", "W(standards)", "W(to)"
        ],
        "varnodes": [],
        "coords": [],
        "n2w": {
            "W(made)": ["made"],
            "W(standards)": ["standards"],
            "**": ["**"],
            "W(to)": ["to"],
            "W(Top)": ["Top"],
            "W(artistic)": ["artistic"],
            "W(A)": ["A"],
            "W(Sandwich)": ["Sandwich"],
            "W(Quality)": ["Quality"]
        }
    }
    g4 = {
        "tokens": [
            "I~1", "wish", "I~2", "had", "you~1", "as", "my~1", "dentist~1",
            "early", "on", "in", "my~2", "life", "-", "maybe", "my~3", "teeth",
            "would", "have", "been", "a", "lot", "better", "then", "they",
            "are~1", "now~1", ",", "However", "I~3", "am", "glad", "you~2",
            "are~2", "my~4", "dentist~2", "now~2", "."
        ],
        "node_edges":
        [["FE1", "FE2", "fe"], ["FE1", "W(as)", "fe"], ["FE1", "W(had)", "fe"],
         ["FE2", "W(early)", "fe*"], ["FE2", "W(in)", "fe"],
         ["FE2", "W(life)", "fe"], ["FE2", "W(my~2)", "fe"],
         ["FE2", "W(on)", "fe"], ["**", "W(However)", None],
         ["**", "W(am)", None], ["**", "W(wish)", None],
         ["**", "W(would)", None], ["W(am)", "W(glad)", None],
         ["W(are~1)", "W(been)", "Anaph"], ["W(are~1)", "W(now~1)", None],
         ["W(are~1)", "W(they)", None], ["W(as)", "W(my~1)", None],
         ["W(been)", "W(better)", None], ["W(better)", "MW(a_lot)", None],
         ["W(better)", "W(then)", None], ["W(glad)", "W(are~2)", None],
         ["W(had)", "W(I~2)", None], ["W(had)", "W(you~1)", None],
         ["W(have)", "W(been)", None], ["W(my~1)", "W(dentist~1)", None],
         ["W(teeth)", "W(my~3)", None], ["W(then)", "W(are~1)", None],
         ["W(wish)", "FE1", None], ["W(would)", "W(have)", None],
         ["W(would)", "W(maybe)", None], ["W(would)", "W(teeth)", None]],
        "nodes": [
            "FE1", "FE2", "MW(a_lot)", "**", "W(However)", "W(I~2)", "W(am)",
            "W(are~1)", "W(are~2)", "W(as)", "W(been)", "W(better)",
            "W(dentist~1)", "W(early)", "W(glad)", "W(had)", "W(have)",
            "W(in)", "W(life)", "W(maybe)", "W(my~1)", "W(my~2)", "W(my~3)",
            "W(now~1)", "W(on)", "W(teeth)", "W(then)", "W(they)", "W(wish)",
            "W(would)", "W(you~1)"
        ],
        "varnodes": [],
        "coords": [],
        "n2w": {
            "W(I~2)": ["I~2"],
            "W(However)": ["However"],
            "W(would)": ["would"],
            "W(then)": ["then"],
            "W(maybe)": ["maybe"],
            "W(my~2)": ["my~2"],
            "W(life)": ["life"],
            "W(are~1)": ["are~1"],
            "W(on)": ["on"],
            "W(as)": ["as"],
            "W(have)": ["have"],
            "W(my~3)": ["my~3"],
            "W(my~1)": ["my~1"],
            "W(they)": ["they"],
            "W(in)": ["in"],
            "**": ["**"],
            "W(wish)": ["wish"],
            "W(had)": ["had"],
            "W(you~1)": ["you~1"],
            "W(teeth)": ["teeth"],
            "W(are~2)": ["are~2"],
            "W(now~1)": ["now~1"],
            "W(better)": ["better"],
            "W(dentist~1)": ["dentist~1"],
            "MW(a_lot)": ["a", "lot"],
            "W(glad)": ["glad"],
            "W(am)": ["am"],
            "W(been)": ["been"],
            "W(early)": ["early"]
        }
    }
    g5 = {
        "tokens": [
            "I~1", "have~1", "purchased", "over", "15", "vehicles", "(",
            "cars", ",", "rvs", ",", "and~1", "boats", ")", "in", "my",
            "lifetime", "and~2", "I~2", "have~2", "to", "say", "the~1",
            "experience", "with", "Michael", "and~3", "Barrett", "Motor",
            "Cars", "of~1", "San", "Antonio", "was", "one", "of~2", "the~2",
            "best", "."
        ],
        "node_edges":
        [["FE1", "W(15)", "fe"], ["FE1", "W(I~1)", "fe"],
         ["FE1", "W(and~1)", "fe"], ["FE1", "W(boats)", "fe"],
         ["FE1", "W(cars)", "fe"], ["FE1", "W(have~1)", "fe*"],
         ["FE1", "W(in)", "fe"], ["FE1", "W(lifetime)", "fe"],
         ["FE1", "W(my)", "fe"], ["FE1", "W(over)", "fe"],
         ["FE1", "W(purchased)", "fe"], ["FE1", "W(rvs)", "fe"],
         ["FE1", "W(vehicles)", "fe"], ["FE2", "W(Antonio)", "fe"],
         ["FE2", "W(Barrett)", "fe"], ["FE2", "W(Cars)", "fe"],
         ["FE2", "W(Michael)", "fe"], ["FE2", "W(Motor)", "fe"],
         ["FE2", "W(San)", "fe"], ["FE2", "W(and~3)", "fe"],
         ["FE2", "W(experience)", "fe"], ["FE2", "W(of~1)", "fe"],
         ["FE2", "W(the~1)", "fe"], ["FE2", "W(with)", "fe"],
         ["FE3", "W(best)", "fe"], ["FE3", "W(of~2)", "fe"],
         ["FE3", "W(one)", "fe"], ["FE3", "W(the~2)", "fe"],
         ["MW(have~2_to)", "W(I~2)", None], ["MW(have~2_to)", "W(say)", None],
         ["**", "FE1", None], ["**", "MW(have~2_to)", None],
         ["**", "W(and~2)", None], ["W(say)", "W(was)", None],
         ["W(was)", "FE2", None], ["W(was)", "FE3", None]],
        "nodes": [
            "FE1", "FE2", "FE3", "MW(have~2_to)", "**", "W(15)", "W(Antonio)",
            "W(Barrett)", "W(Cars)", "W(I~1)", "W(I~2)", "W(Michael)",
            "W(Motor)", "W(San)", "W(and~1)", "W(and~2)", "W(and~3)",
            "W(best)", "W(boats)", "W(cars)", "W(experience)", "W(have~1)",
            "W(in)", "W(lifetime)", "W(my)", "W(of~1)", "W(of~2)", "W(one)",
            "W(over)", "W(purchased)", "W(rvs)", "W(say)", "W(the~1)",
            "W(the~2)", "W(vehicles)", "W(was)", "W(with)"
        ],
        "varnodes": [],
        "coords": [],
        "n2w": {
            "W(San)": ["San"],
            "W(I~2)": ["I~2"],
            "W(and~2)": ["and~2"],
            "W(the~2)": ["the~2"],
            "W(lifetime)": ["lifetime"],
            "W(say)": ["say"],
            "W(Barrett)": ["Barrett"],
            "W(purchased)": ["purchased"],
            "W(vehicles)": ["vehicles"],
            "W(15)": ["15"],
            "W(Cars)": ["Cars"],
            "W(experience)": ["experience"],
            "W(with)": ["with"],
            "W(over)": ["over"],
            "W(rvs)": ["rvs"],
            "W(my)": ["my"],
            "W(cars)": ["cars"],
            "W(in)": ["in"],
            "W(boats)": ["boats"],
            "W(I~1)": ["I~1"],
            "W(and~3)": ["and~3"],
            "**": ["**"],
            "W(the~1)": ["the~1"],
            "W(was)": ["was"],
            "W(and~1)": ["and~1"],
            "W(Motor)": ["Motor"],
            "W(of~1)": ["of~1"],
            "W(one)": ["one"],
            "W(have~1)": ["have~1"],
            "W(Antonio)": ["Antonio"],
            "MW(have~2_to)": ["to", "have~2"],
            "W(of~2)": ["of~2"],
            "W(best)": ["best"],
            "W(Michael)": ["Michael"]
        }
    }
    graphs = [g1, g2, g3, g4, g5]  # last one allows too many analyses?
    for g in graphs:
        f = FUDGGraph(g)
        simplify_coord(f)
        upward(f)
        downward(f)
        for fe in f.fenodes:
            print(fe.name, fe.topcandidates, fe.parentcandidates)
        assert len({n.name for n in f.lexnodes}) == len(f.lexnodes)
        for c in f.lexnodes:
            assert not c.isRoot
            #print(c, c.parentcandidates)
        stg = {(p.name, c.name)
               for c in f.lexnodes for p in c.parentcandidates}
        print(stg)
        print(spanning(stg, '**'))
        print(len(spanning(stg, '**')))