Cleaned code for handout

This commit is contained in:
Mysaa 2023-11-28 19:16:56 +01:00
parent a827e89107
commit 64d1791f8d
Signed by: Mysaa
GPG Key ID: 7054D5D6A90F084F
6 changed files with 429 additions and 997 deletions

429
Report.ipynb Normal file
View File

@ -0,0 +1,429 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from nltk.ccg.api import PrimitiveCategory\n",
"from nltk.ccg.lexicon import CCGLexicon, Token, augParseCategory\n",
"from nltk.ccg.chart import CCGChart,CCGLeafEdge,BinaryCombinatorRule,CCGEdge,CCGChartParser\n",
"from nltk.ccg.chart import compute_semantics,printCCGDerivation\n",
"from nltk.ccg.combinator import *\n",
"from nltk.tree import Tree\n",
"from nltk.sem.logic import Expression\n",
"from numbers import Number\n",
"import pandas as pd\n",
"import numpy as np"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 1. Creating the Lexicon\n",
"\n",
"The lexicon has first been created in a libreoffice spreadsheet, and is under the file `ccg.ods`.\n",
"For each word of the corpus, we gave one, two or three categories in the columns Cat0, Cat1 and Cat2. We also indicated the «classical french grammar name» of the word in order to help us find the catégories. We also did group some words together (with slashes), for example donne/mange have the same catégories, same for le/la/un/mon/ses.\n",
"\n",
"In order to do the rest of the project, we also added a *weight* column for each word group/category couple, and we also added a *semantics* column for each word/category couple, so we could assignate a semantics to be read by the program afterwards.\n",
"\n",
"This allowed us a clean reading, editing and tuning of every parameter of our lexicon.\n",
"\n",
"The spreadsheet is then directly read into the program"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.a Robustness of the grammar\n",
"Our grammar is really simple, as it has really few catégories. Therefore it is really easy to create sentences that are not grammatical. The good counterpart is that there is less probablity that a grammatical sentence will not be parsed.\n",
"\n",
"For exemple, the following agrammatical sentences are parsed:\n",
"- *manger lui donne lui mange*\n",
"- *mon chat mange par elle que souhaite il*\n",
"\n",
"## 2.b Ambiguity\n",
"The main cause of ambiguity is that there is very few catégories, therefore there is a lot of derivation trees going to the same goal. For example, because we do not differenciate *(méchant chat) noir* and *méchant (chat noir)* because both correspond to a reduction (pN pN pN -> pN pN -> pN). Because we have so few catégories, we don't have things like «adjectives order» that would fix the order in which those trees are parsed."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 4. Implementation of the CKY algorithm\n",
"\n",
"This set of functions compiles into the function `bestTree` that returns the best derivation tree of set of tokens, the lexer we extracted from the spreadsheet, and the set of rules.\n",
"\n",
"We define the weight associated to each reduction rule.\n",
"`rweight(rule)` should return the weight associated to the rule, using its string representation (i.e. the name of the rule)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"valz = {\n",
" '>' : 0.8,\n",
" '<' : 0.8,\n",
" '<B' : 0.7,\n",
" '>B' : 0.7\n",
"}\n",
"def rweight(rule):\n",
" s = rule.__str__()\n",
" if s in valz:\n",
" return valz[s]\n",
" else:\n",
" print(\"Unknown rule\",s)\n",
" return 1.0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`weightedParse` implements the CKY algorithm, based on the implementation in the nltk library.\n",
"We take the weight from the weighted lexicon for the leafs, and we compute it using the formula for each reduction rule.\n",
"$$ w_{node} = \\phi_r \\times w_{child1} \\times w_{child2}$$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Implements the CYK algorithm, code partly taken from nltk\n",
"def weightedParse(tokens, lex, rules):\n",
" chart = CCGChart(list(tokens))\n",
" \n",
" # Initialize leaf edges.\n",
" for index in range(chart.num_leaves()):\n",
" for token in lex.categories(chart.leaf(index)):\n",
" new_edge = CCGLeafEdge(index, token, chart.leaf(index))\n",
" new_edge.weight = token.weight()\n",
" chart.insert(new_edge, ())\n",
"\n",
" # Select a span for the new edges\n",
" for span in range(2, chart.num_leaves() + 1):\n",
" for start in range(0, chart.num_leaves() - span + 1):\n",
" \n",
" # edges[s] is the best edge generating the category s\n",
" edges = dict()\n",
" \n",
" # Try all possible pairs of edges that could generate\n",
" # an edge for that span\n",
" for part in range(1, span):\n",
" lstart = start\n",
" mid = start + part\n",
" rend = start + span\n",
" \n",
" # For every pair of edges in (lstart,mid) / (mid,rend).\n",
" # They could be multiple edges if they are two categories on the same span\n",
" for left in chart.select(span=(lstart, mid)):\n",
" for right in chart.select(span=(mid, rend)):\n",
" \n",
" # Generate all possible combinations of the two edges\n",
" for rule in rules:\n",
" \n",
" # Can we apply the rule\n",
" if rule.can_combine(left.categ(), right.categ()):\n",
" \n",
" # If so, we create a (potential) new edge for each new category\n",
" for res in rule.combine(left.categ(), right.categ()):\n",
" \n",
" # res is the new category\n",
" edge = CCGEdge(\n",
" span=(left.start(), right.end()),\n",
" categ=res,\n",
" rule=rule,\n",
" )\n",
" # We compute the weight of the edge\n",
" edge.weight = rweight(rule) * left.weight * right.weight\n",
" # And we log the information of where the triple comes from\n",
" edge.triple = (rule,left,right)\n",
" # We remember the heaviest edge for the specific category\n",
" if not(res in edges and edges[res].weight<=edge.weight):\n",
" edges[res] = edge\n",
" # end for rule loop\n",
" # end for right loop\n",
" # end for left loop\n",
" # end for part loop\n",
" # We add for each category the heaviest edge found\n",
" for cat in edges:\n",
" chart.insert(edges[cat], (edges[cat].triple[1], edges[cat].triple[2]))\n",
" \n",
" # We can return the chart we created\n",
" return chart"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def wp_to_tree(edge, wChart):\n",
" \"\"\"\n",
" This functions takes the biggest edge of a chart and the chart, and send back\n",
" the heaviest tree, that is, the one that generated the weightedParse function.\n",
" \"\"\"\n",
" if isinstance(edge,CCGLeafEdge):\n",
" word = Tree(edge.token(), [wChart._tokens[edge.start()]])\n",
" leaf = Tree((edge.token(), \"Leaf\"), [word])\n",
" return leaf\n",
" else:\n",
" children = [wp_to_tree(t, wChart) for t in (edge.triple[1:])]\n",
" lhs = Token(wChart._tokens[edge.start() : edge.end()],\n",
" edge.lhs(),\n",
" compute_semantics(children, edge))\n",
" return Tree((lhs,edge.triple[0].__str__()), children)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def bestTree(tokens, lex, rules):\n",
" wChart = weightedParse(tokens, lex, rules) # We build the weighgted parse tree using cky\n",
" edge = list(wChart.select(start=0,end=len(tokens)))[0] # We get the biggest edge\n",
" t = wp_to_tree(edge, wChart) # We get the tree that brought us to this edge\n",
" return (t,edge.weight)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Application of the algorithms and the grammar"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Weighed Lexicon"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from warnings import warn\n",
"\n",
"class WeighedToken(Token):\n",
" def __init__(self, token, categ, semantics=None, weight = 1.0):\n",
" super().__init__(token, categ, semantics= semantics)\n",
" self._weight = weight\n",
" def weight(self):\n",
" \"\"\"1.0 is considered the default weight for any token\"\"\"\n",
" try:\n",
" return self._weight\n",
" except AttributeError:\n",
" warn(f\"[{self.token} : {str(self)}] : this token has no weight attribute, defaulted to 1.0.\")\n",
" return 1.0\n",
"\n",
"class WeighedLexicon(CCGLexicon):\n",
" def __init__(self, start, primitives, families, entries):\n",
" super().__init__(start, primitives, families, entries)\n",
"\n",
" def weight(self, entry):\n",
" return entry.weight()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Reading of the spreadsheet"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def to_pseudo_entries(table, consider_semantics = False):\n",
" \"\"\"returns a list of lists in the format ['word', 'category', 'weight', None]\n",
" if consider_semantics == false else ['word', 'category', weight, 'semantic']\n",
" that is left to be converted into tokens by to_wlex_entries\"\"\"\n",
"\n",
" entries = list()\n",
" for line in range(len(table['MOT'])):\n",
" for wdi, word in enumerate(table['MOT'][line].replace(\" \", \"\").split('/')):\n",
" for j in range(3):\n",
" if isinstance(table['Cat'+str(j)][line],str):\n",
" category = table['Cat'+str(j)][line]\n",
" weight = float(table['Weights'+str(j)][line]) if isinstance(table['Weights'+str(j)][line], Number) else 1.0\n",
" if consider_semantics:\n",
" semantic = (table['Sem'+str(j)][line].replace('\\\\\\\\', '\\\\').split('/'))[wdi]\n",
" else:\n",
" semantic = None\n",
" entries.append([word, category, weight, semantic])\n",
" return entries\n",
"\n",
"def to_wlex_entries(pseudo_entries, primitives, families, var=None):\n",
" \"\"\"returns the entries to a weighed lexicon from pseudo_entries generated by to_pseudo_entries\"\"\"\n",
" entries = dict()\n",
" for entry in pseudo_entries:\n",
" if entry[0] not in entries:\n",
" entries[entry[0]] = list()\n",
" categ, _ = augParseCategory(entry[1], primitives, families, var)\n",
" token = WeighedToken(token= entry[0],\n",
" categ= categ,\n",
" semantics= None if entry[-1] is None else Expression.fromstring(entry[-1]),\n",
" weight= entry[2])\n",
" entries[entry[0]].append(token)\n",
" return entries\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Instantiation of the lexicon"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Catégories primitives et familles\n",
"primitives = ['S', 'N', 'Pp', 'pN']\n",
"V = augParseCategory(\"S\\\\N\", primitives = primitives, families={})\n",
"families = {'V': V}\n",
"\n",
"# On importe notre lexique sous forme de tableur\n",
"table = pd.read_excel(\"ccg.ods\", engine=\"odf\")\n",
"#print(table.keys())\n",
"\n",
"# On le convertit en Lexique pondéré\n",
"pe = to_pseudo_entries(table, consider_semantics = True)\n",
"#print(pe)\n",
"wEntries = to_wlex_entries(pseudo_entries= pe, primitives= primitives, families= families)\n",
"#print([list(map(lambda x: f\"{k} : \"+ str(x) + str(x._semantics), L)) for k, L in wEntries.items()])\n",
"lex = WeighedLexicon(start= 'S', primitives= primitives, families= families, entries= wEntries)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Instantiation of the reduction rules"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# On crée le parser, on donne l'ensemble des règles qu'il est cencé connaître\n",
"rulesC = [ForwardApplication,BackwardApplication] \n",
"rulesC += [ForwardComposition,BackwardComposition,BackwardBx]\n",
"rulesC += [ForwardSubstitution,BackwardSx]\n",
"rulesR = [BinaryCombinatorRule(c) for c in rulesC]\n",
"\n",
"parser = CCGChartParser(lex, rulesR)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On lit les phrases depuis le fichier `phrases.txt`, et pour chacune, on imprime le nombre de dérivations trouvées, ainsi que le meilleur arbre de dérivation (i.e. de meilleur poids)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Reading test sentences"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# On lit les phrases dans le fichier\n",
"f = open('phrases.txt')\n",
"lines = f.readlines()\n",
"f.close()\n",
"\n",
"phrases = [p.lower().strip().split() for p in lines]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Running the above algorithms"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for tokens in phrases:\n",
" \n",
" # On compte les arbres de dérivation trouvés\n",
" i = len(list(parser.parse(tokens)))\n",
" print(\"Found\",i,\"derivations for sentence\",*tokens)\n",
"\n",
" # On affiche la dérivation la meilleure pour l'arbre\n",
" if (i != 0):\n",
" t,d = bestTree(tokens, lex, rulesC)\n",
" print(\"Best derivation tree has weight\",d)\n",
" printCCGDerivation(t)\n",
"\n",
" print(\"#\"*42)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(lex)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venv",
"language": "python",
"name": "venv"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@ -1,147 +0,0 @@
from nltk.ccg import chart, lexicon
from nltk.ccg.chart import CCGChart,CCGLeafEdge
from nltk.tree import Tree
import pandas as pd
import numpy as np
valz = {
'>' : 0.8,
'<' : 0.7
}
def rweight(rule):
s = rule.__str__()
if s in valz:
return valz[s]
else:
return 1.0 # Base rules weight
# Implements the CYK algorithm, code partly taken from nltk
def weightedParse(tokens, lex, rules):
chart = CCGChart(list(tokens))
# Initialize leaf edges.
for index in range(chart.num_leaves()):
for token in lex.categories(chart.leaf(index)):
new_edge = CCGLeafEdge(index, token, chart.leaf(index))
new_edge.weight = 1.0
chart.insert(new_edge, ())
# Select a span for the new edges
for span in range(2, chart.num_leaves() + 1):
for start in range(0, chart.num_leaves() - span + 1):
bestedge = None
# Try all possible pairs of edges that could generate
# an edge for that span
for part in range(1, span):
lstart = start
mid = start + part
rend = start + span
for left in chart.select(span=(lstart, mid)):
for right in chart.select(span=(mid, rend)):
# Generate all possible combinations of the two edges
for rule in rules:
edgez = list(rule.apply(chart, lex, left, right))
if(len(edgez)==1):
edge = edgez[0]
edge.weight = rweight(rule) * left.weight * right.weight
edge.triple = (rule,left,right)
if (bestedge == None) or (bestedge.weight < edge.weight):
bestedge = edge
elif(len(edgez)!=0):
print("Too many new edges (unsupported rule used)")
# end for rule loop
# end for right loop
# end for left loop
# end for part loop
return chart
def wpToTree(edge):
if isinstance(edge,CCGLeafEdge):
return Tree((edge.token(),"Leaf"),[Tree(edge.token(),[edge.leaf()])])
else:
return Tree(
(chart.Token(None,edge.categ()),edge.triple[0].__str__()),
[wpToTree(t) for t in (edge.triple[1:])])
def bestTree(tokens, lex, rules):
# We build the weighgted parse tree using cky
w = weightedParse(tokens, lex, rules)
# We get the biggest edge
e = list(w.select(start=0,end=len(tokens)))[0]
# We get the tree that brought us to this edge
return (wpToTree(e),e.weight)
# On importe notre lexique sous forme de tableur
table = pd.read_excel("CategoriesGramaticalesCombinatoire.ods", engine="odf")
# On récupère le nombre de mots qui ont été définis
n = len(table['MOT'])
# On donne la liste des catégories primitives
lexstring=':- S,N,Pp\n'
# On ajoute la notation V pour N\S
lexstring+='V :: S\\N\n'
# On lis les données depuis le tableur en une chaine de caractère parsable
for i in range(n):
for j in range(3):
if isinstance(table['Cat'+str(j)][i],str):
for mot in table['MOT'][i].split('/'):
lexstring+=mot+' => ' + table['Cat'+str(j)][i] + '\n'
# Pour inverser les slash dans le lexicon
#lexstring = lexstring.replace('\\','#').replace('/','\\').replace('#','/')
# On crée notre lexique
lex = lexicon.fromstring(lexstring)
# On crée le parser, on donne l'ensemble des règles qu'il est cencé connaître
parser = chart.CCGChartParser(lex, chart.DefaultRuleSet)
#parser = chart.CCGChartParser(lex, chart.ApplicationRuleSet)
printTotal=True
printDerivations=not printTotal
# On lit les phrases dans le fichier
with open('phrases.txt') as f:
lines = f.readlines()
lines.append("le chat et la souris dorment")
for phrase in lines:
# On met tout en minuscule
phrase = phrase.lower().strip()
if printDerivations:
print("============================================================================")
print('#',phrase)
lex = lexicon.fromstring(lexstring)
parser = chart.CCGChartParser(lex, chart.ApplicationRuleSet)
# Et on affiche tous les arbres de dérivation trouvés
i=0
for parse in parser.parse(phrase.split()):
i+=1
if printDerivations:
chart.printCCGDerivation(parse)
if printTotal:
print(i,phrase)
# On affiche la dérivation la meilleure pour l'arbre
if (i==0):
print("Pas de dérivation tout court :/")
else:
t,d = bestTree(phrase.split(), lex, chart.ApplicationRuleSet)
print("Found derivation tree with weight",d)
chart.printCCGDerivation(t)

View File

@ -1,18 +0,0 @@
from nltk.ccg import chart, lexicon
import pandas as pd
import numpy as np
lexstring='''
:- S,N
chat => N
dort => N\S
'''
lex = lexicon.fromstring(lexstring)
print(lex)
parser = chart.CCGChartParser(lex, chart.ApplicationRuleSet)
phrase="chat dort"
for parse in parser.parse(phrase.split()):
chart.printCCGDerivation(parse)

View File

@ -1,61 +0,0 @@
from nltk.ccg import chart, lexicon
lex = lexicon.fromstring('''
:- S, NP, N, VP
Det :: NP/N
Pro :: NP
Modal :: S\\NP/VP
TV :: VP/NP
DTV :: TV/NP
the => Det
that => Det
that => NP
I => Pro
you => Pro
we => Pro
chef => N
cake => N
children => N
dough => N
will => Modal
should => Modal
might => Modal
must => Modal
and => var\\.,var/.,var
to => VP[to]/VP
without => (VP\\VP)/VP[ing]
be => TV
cook => TV
eat => TV
cooking => VP[ing]/NP
give => DTV
is => (S\\NP)/NP
prefer => (S\\NP)/NP
which => (N\\N)/(S/NP)
persuade => (VP/VP[to])/NP
''')
parser = chart.CCGChartParser(lex, chart.DefaultRuleSet)
for parse in parser.parse("you prefer that cake".split()):
chart.printCCGDerivation(parse)
break
for parse in parser.parse("that is the cake which you prefer".split()):
chart.printCCGDerivation(parse)
break

View File

@ -1,771 +0,0 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from nltk.ccg import chart, lexicon\n",
"from nltk.ccg.lexicon import CCGLexicon, Token, augParseCategory\n",
"from nltk.ccg.chart import CCGChart,CCGLeafEdge,BinaryCombinatorRule,CCGEdge,compute_semantics\n",
"from nltk.tree import Tree\n",
"import pandas as pd\n",
"import numpy as np"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Weighed Lexicon"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from warnings import warn\n",
"\n",
"class WeighedToken(Token):\n",
" def __init__(self, token, categ, semantics=None, weight = 1.0):\n",
" super().__init__(token, categ, semantics= semantics)\n",
" self._weight = weight\n",
" def weight(self):\n",
" \"\"\"1.0 is considered the default weight for any token\"\"\"\n",
" try:\n",
" return self._weight\n",
" except AttributeError:\n",
" warn(f\"[{self.token} : {str(self)}] : this token has no weight attribute, defaulted to 1.0.\")\n",
" return 1.0\n",
"\n",
"class WeighedLexicon(CCGLexicon):\n",
" def __init__(self, start, primitives, families, entries):\n",
" super().__init__(start, primitives, families, entries)\n",
"\n",
" def weight(self, entry):\n",
" return entry.weight()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# CYK"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We define the weight associated to each reduction rule.\n",
"`rweight(rule)` should return the weight associated to the rul, using its string representation (i.e. the name of the rule)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"valz = {\n",
" '>' : 0.8,\n",
" '<' : 0.7\n",
"}\n",
"def rweight(rule):\n",
" s = rule.__str__()\n",
" if s in valz:\n",
" return valz[s]\n",
" else:\n",
" print(\"Unknown rule\",s)\n",
" return 1.0 # Base rules weight"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`weightedParse` implements the CKY algorithm, based on the implementation in the nltk library.\n",
"We take the weight from the weighted lexicon for the leafs, and we compute it using the formula for each reduction rule.\n",
"$$ w_{node} = \\phi_r \\times w_{child1} \\times w_{child2}$$"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"# Implements the CYK algorithm, code partly taken from nltk\n",
"def weightedParse(tokens, lex, rules):\n",
" chart = CCGChart(list(tokens))\n",
" \n",
" # Initialize leaf edges.\n",
" for index in range(chart.num_leaves()):\n",
" for token in lex.categories(chart.leaf(index)):\n",
" new_edge = CCGLeafEdge(index, token, chart.leaf(index))\n",
" new_edge.weight = token.weight()\n",
" chart.insert(new_edge, ())\n",
"\n",
" # Select a span for the new edges\n",
" for span in range(2, chart.num_leaves() + 1):\n",
" for start in range(0, chart.num_leaves() - span + 1):\n",
" \n",
" bestedge = None\n",
" nedg = 0\n",
" # edges[s] is the best edge generating the category s\n",
" edges = dict()\n",
" \n",
" # Try all possible pairs of edges that could generate\n",
" # an edge for that span\n",
" for part in range(1, span):\n",
" lstart = start\n",
" mid = start + part\n",
" rend = start + span\n",
" \n",
" for left in chart.select(span=(lstart, mid)):\n",
" for right in chart.select(span=(mid, rend)):\n",
" # Generate all possible combinations of the two edges\n",
" for rule in rules:\n",
" # Can we apply the rule\n",
" if rule.can_combine(left.categ(), right.categ()):\n",
" for res in rule.combine(left.categ(), right.categ()):\n",
" # res is the new category\n",
" edge = CCGEdge(\n",
" span=(left.start(), right.end()),\n",
" categ=res,\n",
" rule=rule,\n",
" )\n",
" edge.weight = rweight(rule) * left.weight * right.weight\n",
" edge.triple = (rule,left,right)\n",
" if not(res in edges and edges[res].weight<=edge.weight):\n",
" edges[res] = edge\n",
" # end for rule loop\n",
" # end for right loop\n",
" # end for left loop\n",
" # end for part loop\n",
" for cat in edges:\n",
" chart.insert(edges[cat], (edges[cat].triple[1], edges[cat].triple[2]))\n",
" return chart"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"def wp_to_tree(edge, wChart):\n",
" if isinstance(edge,CCGLeafEdge):\n",
" word = Tree(edge.token(), [wChart._tokens[edge.start()]])\n",
" leaf = Tree((edge.token(), \"Leaf\"), [word])\n",
" return leaf\n",
" else:\n",
" children = [wp_to_tree(t, wChart) for t in (edge.triple[1:])]\n",
" lhs = Token(wChart._tokens[edge.start() : edge.end()],\n",
" edge.lhs(),\n",
" compute_semantics(children, edge))\n",
" return Tree((lhs,edge.triple[0].__str__()), children)"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [],
"source": [
"def bestTree(tokens, lex, rules):\n",
" wChart = weightedParse(tokens, lex, rules) # We build the weighgted parse tree using cky\n",
" edge = list(wChart.select(start=0,end=len(tokens)))[0] # We get the biggest edge\n",
" t = wp_to_tree(edge, wChart) # We get the tree that brought us to this edge\n",
" return (t,edge.weight)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Application"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [],
"source": [
"from numbers import Number\n",
"from nltk.sem.logic import Expression\n",
"from nltk.ccg.api import PrimitiveCategory\n",
"\n",
"def to_pseudo_entries(table, consider_semantics = False):\n",
" \"\"\"returns a list of lists in the format ['word', 'category', 'weight', None]\n",
" if consider_semantics == false else ['word', 'category', weight, 'semantic']\n",
" that is left to be converted into tokens by to_wlex_entries\"\"\"\n",
"\n",
" entries = list()\n",
" for line in range(len(table['MOT'])):\n",
" for wdi, word in enumerate(table['MOT'][line].replace(\" \", \"\").split('/')):\n",
" for j in range(3):\n",
" if isinstance(table['Cat'+str(j)][line],str):\n",
" category = table['Cat'+str(j)][line]\n",
" weight = float(table['Weights'+str(j)][line]) if isinstance(table['Weights'+str(j)][line], Number) else 1.0\n",
" if consider_semantics:\n",
" semantic = (table['Sem'+str(j)][line].replace('\\\\\\\\', '\\\\').split('/'))[wdi]\n",
" else:\n",
" semantic = None\n",
" entries.append([word, category, weight, semantic])\n",
" return entries\n",
"\n",
"def to_wlex_entries(pseudo_entries, primitives, families, var=None):\n",
" \"\"\"returns the entries to a weighed lexicon from pseudo_entries generated by to_pseudo_entries\"\"\"\n",
" entries = dict()\n",
" for entry in pseudo_entries:\n",
" if entry[0] not in entries:\n",
" entries[entry[0]] = list()\n",
" categ, _ = augParseCategory(entry[1], primitives, families, var)\n",
" token = WeighedToken(token= entry[0],\n",
" categ= categ,\n",
" semantics= None if entry[-1] is None else Expression.fromstring(entry[-1]),\n",
" weight= entry[2])\n",
" entries[entry[0]].append(token)\n",
" return entries\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We create our lexicon using the data from the server"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [],
"source": [
"# Catégories primitives et familles\n",
"primitives = ['S', 'N', 'Pp', 'pN']\n",
"V = augParseCategory(\"S\\\\N\", primitives = primitives, families={})\n",
"families = {'V': V}\n",
"\n",
"# On importe notre lexique sous forme de tableur\n",
"table = pd.read_excel(\"CategoriesGramaticalesCombinatoire.ods\", engine=\"odf\")\n",
"#print(table.keys())\n",
"\n",
"# On le convertit en Lexique pondéré\n",
"pe = to_pseudo_entries(table, consider_semantics = True)\n",
"#print(pe)\n",
"wEntries = to_wlex_entries(pseudo_entries= pe, primitives= primitives, families= families)\n",
"#print([list(map(lambda x: f\"{k} : \"+ str(x) + str(x._semantics), L)) for k, L in wEntries.items()])\n",
"lex = WeighedLexicon(start= 'S', primitives= primitives, families= families, entries= wEntries)\n",
"\n",
"\n",
"# On crée le parser, on donne l'ensemble des règles qu'il est cencé connaître\n",
"from nltk.ccg.combinator import (\n",
" BackwardApplication,\n",
" BackwardBx,\n",
" BackwardComposition,\n",
" BackwardSx,\n",
" ForwardApplication,\n",
" ForwardComposition,\n",
" ForwardSubstitution\n",
")\n",
"rulesC = [ForwardApplication,BackwardApplication] \n",
"rulesC += [ForwardComposition,BackwardComposition,BackwardBx]\n",
"rulesC += [ForwardSubstitution,BackwardSx]\n",
"rulesR = [BinaryCombinatorRule(c) for c in rulesC]\n",
"# chart.ApplicationRuleSet for only < and >\n",
"\n",
"parser = chart.CCGChartParser(lex, rulesR)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On lit les phrases depuis le fichier `phrases.txt`, et pour chacune, on imprime le nombre de dérivations trouvées, ainsi que le meilleur arbre de dérivation (i.e. de meilleur poids)"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1 found derivation for sentence: le chat dort\n",
" le chat dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"------------------------------------------------------------<\n",
" S {dormir(exists x.chat(x))}\n",
"Best derivation tree has weight 0.5599999999999999\n",
" le chat dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"------------------------------------------------------------<\n",
" S {dormir(exists x.chat(x))}\n",
"##########################################\n",
"1 found derivation for sentence: il dort\n",
" il dort\n",
" N {il} (S\\N) {\\n.dormir(n)}\n",
"------------------------------<\n",
" S {dormir(il)}\n",
"Best derivation tree has weight 0.7\n",
" il dort\n",
" N {il} (S\\N) {\\n.dormir(n)}\n",
"------------------------------<\n",
" S {dormir(il)}\n",
"##########################################\n",
"1 found derivation for sentence: le chat dort paisiblement\n",
" le chat dort paisiblement\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} (S\\N) {\\n.dormir(n)} ((S\\N)\\(S\\N)) {\\V n.paisiblement(V(n))}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
" ---------------------------------------------------------------<\n",
" (S\\N) {\\n.paisiblement(dormir(n))}\n",
"-----------------------------------------------------------------------------------------------------<\n",
" S {paisiblement(dormir(exists x.chat(x)))}\n",
"Best derivation tree has weight 0.39199999999999996\n",
" le chat dort paisiblement\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} (S\\N) {\\n.dormir(n)} ((S\\N)\\(S\\N)) {\\V n.paisiblement(V(n))}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
" ---------------------------------------------------------------<\n",
" (S\\N) {\\n.paisiblement(dormir(n))}\n",
"-----------------------------------------------------------------------------------------------------<\n",
" S {paisiblement(dormir(exists x.chat(x)))}\n",
"##########################################\n",
"1 found derivation for sentence: le chat noir dort\n",
" le chat noir dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} (pN\\pN) {\\n.noir(n)} (S\\N) {\\n.dormir(n)}\n",
" ---------------------------------<\n",
" pN {noir(chat)}\n",
"------------------------------------------------------------>\n",
" N {exists x.noir(chat,x)}\n",
"----------------------------------------------------------------------------------<\n",
" S {dormir(exists x.noir(chat,x))}\n",
"Best derivation tree has weight 0.39199999999999996\n",
" le chat noir dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} (pN\\pN) {\\n.noir(n)} (S\\N) {\\n.dormir(n)}\n",
" ---------------------------------<\n",
" pN {noir(chat)}\n",
"------------------------------------------------------------>\n",
" N {exists x.noir(chat,x)}\n",
"----------------------------------------------------------------------------------<\n",
" S {dormir(exists x.noir(chat,x))}\n",
"##########################################\n",
"2 found derivation for sentence: le méchant chat dort\n",
" le méchant chat dort\n",
" (N/pN) {\\P.exists x.P(x)} (pN/pN) {\\n.méchant(n)} pN {chat} (S\\N) {\\n.dormir(n)}\n",
" ------------------------------------>\n",
" pN {méchant(chat)}\n",
"--------------------------------------------------------------->\n",
" N {exists x.méchant(chat,x)}\n",
"-------------------------------------------------------------------------------------<\n",
" S {dormir(exists x.méchant(chat,x))}\n",
" le méchant chat dort\n",
" (N/pN) {\\P.exists x.P(x)} (pN/pN) {\\n.méchant(n)} pN {chat} (S\\N) {\\n.dormir(n)}\n",
"---------------------------------------------------->B\n",
" (N/pN) {\\n.exists x.méchant(n,x)}\n",
"--------------------------------------------------------------->\n",
" N {exists x.méchant(chat,x)}\n",
"-------------------------------------------------------------------------------------<\n",
" S {dormir(exists x.méchant(chat,x))}\n",
"Unknown rule >B\n",
"Unknown rule >B\n",
"Best derivation tree has weight 0.44800000000000006\n",
" le méchant chat dort\n",
" (N/pN) {\\P.exists x.P(x)} (pN/pN) {\\n.méchant(n)} pN {chat} (S\\N) {\\n.dormir(n)}\n",
" ------------------------------------>\n",
" pN {méchant(chat)}\n",
"--------------------------------------------------------------->\n",
" N {exists x.méchant(chat,x)}\n",
"-------------------------------------------------------------------------------------<\n",
" S {dormir(exists x.méchant(chat,x))}\n",
"##########################################\n",
"4 found derivation for sentence: le très méchant chat dort\n",
" le très méchant chat dort\n",
" (N/pN) {\\P.exists x.P(x)} ((pN/pN)/(pN/pN)) {\\P n.très(P(n))} (pN/pN) {\\n.méchant(n)} pN {chat} (S\\N) {\\n.dormir(n)}\n",
" -------------------------------------------------------------->\n",
" (pN/pN) {\\n.très(méchant(n))}\n",
" ------------------------------------------------------------------------->\n",
" pN {très(méchant(chat))}\n",
"---------------------------------------------------------------------------------------------------->\n",
" N {exists x.très(méchant(chat),x)}\n",
"--------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(exists x.très(méchant(chat),x))}\n",
" le très méchant chat dort\n",
" (N/pN) {\\P.exists x.P(x)} ((pN/pN)/(pN/pN)) {\\P n.très(P(n))} (pN\\pN) {\\n.méchant(n)} pN {chat} (S\\N) {\\n.dormir(n)}\n",
" -------------------------------------------------------------->\n",
" (pN/pN) {\\n.très(méchant(n))}\n",
" ------------------------------------------------------------------------->\n",
" pN {très(méchant(chat))}\n",
"---------------------------------------------------------------------------------------------------->\n",
" N {exists x.très(méchant(chat),x)}\n",
"--------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(exists x.très(méchant(chat),x))}\n",
" le très méchant chat dort\n",
" (N/pN) {\\P.exists x.P(x)} ((pN/pN)/(pN/pN)) {\\P n.très(P(n))} (pN/pN) {\\n.méchant(n)} pN {chat} (S\\N) {\\n.dormir(n)}\n",
" -------------------------------------------------------------->\n",
" (pN/pN) {\\n.très(méchant(n))}\n",
"----------------------------------------------------------------------------------------->B\n",
" (N/pN) {\\n.exists x.très(méchant(n),x)}\n",
"---------------------------------------------------------------------------------------------------->\n",
" N {exists x.très(méchant(chat),x)}\n",
"--------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(exists x.très(méchant(chat),x))}\n",
" le très méchant chat dort\n",
" (N/pN) {\\P.exists x.P(x)} ((pN/pN)/(pN/pN)) {\\P n.très(P(n))} (pN\\pN) {\\n.méchant(n)} pN {chat} (S\\N) {\\n.dormir(n)}\n",
" -------------------------------------------------------------->\n",
" (pN/pN) {\\n.très(méchant(n))}\n",
"----------------------------------------------------------------------------------------->B\n",
" (N/pN) {\\n.exists x.très(méchant(n),x)}\n",
"---------------------------------------------------------------------------------------------------->\n",
" N {exists x.très(méchant(chat),x)}\n",
"--------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(exists x.très(méchant(chat),x))}\n",
"Unknown rule >B\n",
"Best derivation tree has weight 0.35840000000000005\n",
" le très méchant chat dort\n",
" (N/pN) {\\P.exists x.P(x)} ((pN/pN)/(pN/pN)) {\\P n.très(P(n))} (pN/pN) {\\n.méchant(n)} pN {chat} (S\\N) {\\n.dormir(n)}\n",
" -------------------------------------------------------------->\n",
" (pN/pN) {\\n.très(méchant(n))}\n",
" ------------------------------------------------------------------------->\n",
" pN {très(méchant(chat))}\n",
"---------------------------------------------------------------------------------------------------->\n",
" N {exists x.très(méchant(chat),x)}\n",
"--------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(exists x.très(méchant(chat),x))}\n",
"##########################################\n",
"9 found derivation for sentence: le chat de la sœur de mon voisin dort\n",
" le chat de la sœur de mon voisin dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {voisin} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.chat(x),m)}\n",
" --------------------------------------->\n",
" N {exists x.soeur(x)}\n",
" -----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.soeur(x),m)}\n",
" ---------------------------------------->\n",
" N {exists x.voisin(x)}\n",
" --------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.soeur(x),exists x.voisin(x))}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x)))}\n",
"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x))))}\n",
" le chat de la sœur de mon voisin dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {voisin} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.chat(x),m)}\n",
" --------------------------------------->\n",
" N {exists x.soeur(x)}\n",
" -----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.soeur(x),m)}\n",
" -------------------------------------------------------------------------------------------->B\n",
" (N/pN) {\\P.de(exists x.soeur(x),exists x.P(x))}\n",
" --------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.soeur(x),exists x.voisin(x))}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x)))}\n",
"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x))))}\n",
" le chat de la sœur de mon voisin dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {voisin} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.chat(x),m)}\n",
" --------------------------------------->\n",
" N {exists x.soeur(x)}\n",
" -----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.soeur(x),m)}\n",
"--------------------------------------------------------------------------------------------------------------------------------->B\n",
" (N/N) {\\m.de(exists x.chat(x),de(exists x.soeur(x),m))}\n",
" ---------------------------------------->\n",
" N {exists x.voisin(x)}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x)))}\n",
"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x))))}\n",
" le chat de la sœur de mon voisin dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {voisin} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.chat(x),m)}\n",
" --------------------------------------->\n",
" N {exists x.soeur(x)}\n",
"------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.chat(x),exists x.soeur(x))}\n",
"---------------------------------------------------------------------------------------------------------------------------------<\n",
" (N/N) {\\m.de(de(exists x.chat(x),exists x.soeur(x)),m)}\n",
" ---------------------------------------->\n",
" N {exists x.voisin(x)}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n",
" N {de(de(exists x.chat(x),exists x.soeur(x)),exists x.voisin(x))}\n",
"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(de(de(exists x.chat(x),exists x.soeur(x)),exists x.voisin(x)))}\n",
" le chat de la sœur de mon voisin dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {voisin} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.chat(x),m)}\n",
"------------------------------------------------------------------------------------------->B\n",
" (N/pN) {\\P.de(exists x.chat(x),exists x.P(x))}\n",
"------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.chat(x),exists x.soeur(x))}\n",
"---------------------------------------------------------------------------------------------------------------------------------<\n",
" (N/N) {\\m.de(de(exists x.chat(x),exists x.soeur(x)),m)}\n",
" ---------------------------------------->\n",
" N {exists x.voisin(x)}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n",
" N {de(de(exists x.chat(x),exists x.soeur(x)),exists x.voisin(x))}\n",
"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(de(de(exists x.chat(x),exists x.soeur(x)),exists x.voisin(x)))}\n",
" le chat de la sœur de mon voisin dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {voisin} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.chat(x),m)}\n",
" --------------------------------------->\n",
" N {exists x.soeur(x)}\n",
" -----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.soeur(x),m)}\n",
" -------------------------------------------------------------------------------------------->B\n",
" (N/pN) {\\P.de(exists x.soeur(x),exists x.P(x))}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------>B\n",
" (N/pN) {\\P.de(exists x.chat(x),de(exists x.soeur(x),exists x.P(x)))}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x)))}\n",
"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x))))}\n",
" le chat de la sœur de mon voisin dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {voisin} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.chat(x),m)}\n",
" --------------------------------------->\n",
" N {exists x.soeur(x)}\n",
" -----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.soeur(x),m)}\n",
"--------------------------------------------------------------------------------------------------------------------------------->B\n",
" (N/N) {\\m.de(exists x.chat(x),de(exists x.soeur(x),m))}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------>B\n",
" (N/pN) {\\P.de(exists x.chat(x),de(exists x.soeur(x),exists x.P(x)))}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x)))}\n",
"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x))))}\n",
" le chat de la sœur de mon voisin dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {voisin} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.chat(x),m)}\n",
" --------------------------------------->\n",
" N {exists x.soeur(x)}\n",
"------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.chat(x),exists x.soeur(x))}\n",
"---------------------------------------------------------------------------------------------------------------------------------<\n",
" (N/N) {\\m.de(de(exists x.chat(x),exists x.soeur(x)),m)}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------>B\n",
" (N/pN) {\\P.de(de(exists x.chat(x),exists x.soeur(x)),exists x.P(x))}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n",
" N {de(de(exists x.chat(x),exists x.soeur(x)),exists x.voisin(x))}\n",
"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(de(de(exists x.chat(x),exists x.soeur(x)),exists x.voisin(x)))}\n",
" le chat de la sœur de mon voisin dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {voisin} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.chat(x),m)}\n",
"------------------------------------------------------------------------------------------->B\n",
" (N/pN) {\\P.de(exists x.chat(x),exists x.P(x))}\n",
"------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.chat(x),exists x.soeur(x))}\n",
"---------------------------------------------------------------------------------------------------------------------------------<\n",
" (N/N) {\\m.de(de(exists x.chat(x),exists x.soeur(x)),m)}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------>B\n",
" (N/pN) {\\P.de(de(exists x.chat(x),exists x.soeur(x)),exists x.P(x))}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n",
" N {de(de(exists x.chat(x),exists x.soeur(x)),exists x.voisin(x))}\n",
"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(de(de(exists x.chat(x),exists x.soeur(x)),exists x.voisin(x)))}\n",
"Unknown rule >B\n",
"Unknown rule >B\n",
"Unknown rule >B\n",
"Unknown rule >B\n",
"Unknown rule >B\n",
"Best derivation tree has weight 0.11239423999999998\n",
" le chat de la sœur de mon voisin dort\n",
" (N/pN) {\\P.exists x.P(x)} pN {chat} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {soeur} ((N/N)\\N) {\\n m.de(n,m)} (N/pN) {\\P.exists x.P(x)} pN {voisin} (S\\N) {\\n.dormir(n)}\n",
"-------------------------------------->\n",
" N {exists x.chat(x)}\n",
"----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.chat(x),m)}\n",
" --------------------------------------->\n",
" N {exists x.soeur(x)}\n",
" -----------------------------------------------------------------<\n",
" (N/N) {\\m.de(exists x.soeur(x),m)}\n",
" ---------------------------------------->\n",
" N {exists x.voisin(x)}\n",
" --------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.soeur(x),exists x.voisin(x))}\n",
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------->\n",
" N {de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x)))}\n",
"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<\n",
" S {dormir(de(exists x.chat(x),de(exists x.soeur(x),exists x.voisin(x))))}\n",
"##########################################\n"
]
},
{
"ename": "AssertionError",
"evalue": "`{}(\\m.à(donne(exists x.voisin(x)),m))` must be a lambda expression",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[52], line 10\u001b[0m\n\u001b[1;32m 7\u001b[0m phrase \u001b[38;5;241m=\u001b[39m phrase\u001b[38;5;241m.\u001b[39mlower()\u001b[38;5;241m.\u001b[39mstrip()\n\u001b[1;32m 9\u001b[0m \u001b[38;5;66;03m# On compte les arbres de dérivation trouvés\u001b[39;00m\n\u001b[0;32m---> 10\u001b[0m i \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28mlist\u001b[39m(parser\u001b[38;5;241m.\u001b[39mparse(phrase\u001b[38;5;241m.\u001b[39msplit())))\n\u001b[1;32m 11\u001b[0m \u001b[38;5;28mprint\u001b[39m(i, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfound derivation for sentence:\u001b[39m\u001b[38;5;124m\"\u001b[39m,phrase)\n\u001b[1;32m 12\u001b[0m g \u001b[38;5;241m=\u001b[39m parser\u001b[38;5;241m.\u001b[39mparse(phrase\u001b[38;5;241m.\u001b[39msplit())\n",
"File \u001b[0;32m~/Documents/Arbeiten/Linguistique/.env/lib/python3.11/site-packages/nltk/parse/chart.py:677\u001b[0m, in \u001b[0;36mChart.parses\u001b[0;34m(self, root, tree_class)\u001b[0m\n\u001b[1;32m 672\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 673\u001b[0m \u001b[38;5;124;03mReturn an iterator of the complete tree structures that span\u001b[39;00m\n\u001b[1;32m 674\u001b[0m \u001b[38;5;124;03mthe entire chart, and whose root node is ``root``.\u001b[39;00m\n\u001b[1;32m 675\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 676\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m edge \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mselect(start\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0\u001b[39m, end\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_leaves, lhs\u001b[38;5;241m=\u001b[39mroot):\n\u001b[0;32m--> 677\u001b[0m \u001b[38;5;28;01myield from\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtrees\u001b[49m\u001b[43m(\u001b[49m\u001b[43medge\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtree_class\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtree_class\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcomplete\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m~/Documents/Arbeiten/Linguistique/.env/lib/python3.11/site-packages/nltk/parse/chart.py:694\u001b[0m, in \u001b[0;36mChart.trees\u001b[0;34m(self, edge, tree_class, complete)\u001b[0m\n\u001b[1;32m 679\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mtrees\u001b[39m(\u001b[38;5;28mself\u001b[39m, edge, tree_class\u001b[38;5;241m=\u001b[39mTree, complete\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m):\n\u001b[1;32m 680\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 681\u001b[0m \u001b[38;5;124;03m Return an iterator of the tree structures that are associated\u001b[39;00m\n\u001b[1;32m 682\u001b[0m \u001b[38;5;124;03m with ``edge``.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 692\u001b[0m \u001b[38;5;124;03m sharing, then create a deep copy of each tree.\u001b[39;00m\n\u001b[1;32m 693\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 694\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28miter\u001b[39m(\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_trees\u001b[49m\u001b[43m(\u001b[49m\u001b[43medge\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcomplete\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmemo\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m{\u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtree_class\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtree_class\u001b[49m\u001b[43m)\u001b[49m)\n",
"File \u001b[0;32m~/Documents/Arbeiten/Linguistique/.env/lib/python3.11/site-packages/nltk/ccg/chart.py:332\u001b[0m, in \u001b[0;36mCCGChart._trees\u001b[0;34m(self, edge, complete, memo, tree_class)\u001b[0m\n\u001b[1;32m 329\u001b[0m trees \u001b[38;5;241m=\u001b[39m []\n\u001b[1;32m 331\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m cpl \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mchild_pointer_lists(edge):\n\u001b[0;32m--> 332\u001b[0m child_choices \u001b[38;5;241m=\u001b[39m \u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_trees\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcp\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcomplete\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmemo\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtree_class\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mcp\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mcpl\u001b[49m\u001b[43m]\u001b[49m\n\u001b[1;32m 333\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m children \u001b[38;5;129;01min\u001b[39;00m itertools\u001b[38;5;241m.\u001b[39mproduct(\u001b[38;5;241m*\u001b[39mchild_choices):\n\u001b[1;32m 334\u001b[0m lhs \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 335\u001b[0m Token(\n\u001b[1;32m 336\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_tokens[edge\u001b[38;5;241m.\u001b[39mstart() : edge\u001b[38;5;241m.\u001b[39mend()],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 340\u001b[0m \u001b[38;5;28mstr\u001b[39m(edge\u001b[38;5;241m.\u001b[39mrule()),\n\u001b[1;32m 341\u001b[0m )\n",
"File \u001b[0;32m~/Documents/Arbeiten/Linguistique/.env/lib/python3.11/site-packages/nltk/ccg/chart.py:332\u001b[0m, in \u001b[0;36m<listcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 329\u001b[0m trees \u001b[38;5;241m=\u001b[39m []\n\u001b[1;32m 331\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m cpl \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mchild_pointer_lists(edge):\n\u001b[0;32m--> 332\u001b[0m child_choices \u001b[38;5;241m=\u001b[39m [\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_trees\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcp\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcomplete\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmemo\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtree_class\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m cp \u001b[38;5;129;01min\u001b[39;00m cpl]\n\u001b[1;32m 333\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m children \u001b[38;5;129;01min\u001b[39;00m itertools\u001b[38;5;241m.\u001b[39mproduct(\u001b[38;5;241m*\u001b[39mchild_choices):\n\u001b[1;32m 334\u001b[0m lhs \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 335\u001b[0m Token(\n\u001b[1;32m 336\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_tokens[edge\u001b[38;5;241m.\u001b[39mstart() : edge\u001b[38;5;241m.\u001b[39mend()],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 340\u001b[0m \u001b[38;5;28mstr\u001b[39m(edge\u001b[38;5;241m.\u001b[39mrule()),\n\u001b[1;32m 341\u001b[0m )\n",
"File \u001b[0;32m~/Documents/Arbeiten/Linguistique/.env/lib/python3.11/site-packages/nltk/ccg/chart.py:338\u001b[0m, in \u001b[0;36mCCGChart._trees\u001b[0;34m(self, edge, complete, memo, tree_class)\u001b[0m\n\u001b[1;32m 332\u001b[0m child_choices \u001b[38;5;241m=\u001b[39m [\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_trees(cp, complete, memo, tree_class) \u001b[38;5;28;01mfor\u001b[39;00m cp \u001b[38;5;129;01min\u001b[39;00m cpl]\n\u001b[1;32m 333\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m children \u001b[38;5;129;01min\u001b[39;00m itertools\u001b[38;5;241m.\u001b[39mproduct(\u001b[38;5;241m*\u001b[39mchild_choices):\n\u001b[1;32m 334\u001b[0m lhs \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 335\u001b[0m Token(\n\u001b[1;32m 336\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_tokens[edge\u001b[38;5;241m.\u001b[39mstart() : edge\u001b[38;5;241m.\u001b[39mend()],\n\u001b[1;32m 337\u001b[0m edge\u001b[38;5;241m.\u001b[39mlhs(),\n\u001b[0;32m--> 338\u001b[0m \u001b[43mcompute_semantics\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchildren\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43medge\u001b[49m\u001b[43m)\u001b[49m,\n\u001b[1;32m 339\u001b[0m ),\n\u001b[1;32m 340\u001b[0m \u001b[38;5;28mstr\u001b[39m(edge\u001b[38;5;241m.\u001b[39mrule()),\n\u001b[1;32m 341\u001b[0m )\n\u001b[1;32m 342\u001b[0m trees\u001b[38;5;241m.\u001b[39mappend(tree_class(lhs, children))\n\u001b[1;32m 344\u001b[0m memo[edge] \u001b[38;5;241m=\u001b[39m trees\n",
"File \u001b[0;32m~/Documents/Arbeiten/Linguistique/.env/lib/python3.11/site-packages/nltk/ccg/chart.py:363\u001b[0m, in \u001b[0;36mcompute_semantics\u001b[0;34m(children, edge)\u001b[0m\n\u001b[1;32m 361\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m compute_function_semantics(function, argument)\n\u001b[1;32m 362\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(combinator, UndirectedComposition):\n\u001b[0;32m--> 363\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcompute_composition_semantics\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfunction\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43margument\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 364\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(combinator, UndirectedSubstitution):\n\u001b[1;32m 365\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m compute_substitution_semantics(function, argument)\n",
"File \u001b[0;32m~/Documents/Arbeiten/Linguistique/.env/lib/python3.11/site-packages/nltk/ccg/logic.py:39\u001b[0m, in \u001b[0;36mcompute_composition_semantics\u001b[0;34m(function, argument)\u001b[0m\n\u001b[1;32m 38\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcompute_composition_semantics\u001b[39m(function, argument):\n\u001b[0;32m---> 39\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(argument, LambdaExpression), (\n\u001b[1;32m 40\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(argument) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m` must be a lambda expression\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 41\u001b[0m )\n\u001b[1;32m 42\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m LambdaExpression(\n\u001b[1;32m 43\u001b[0m argument\u001b[38;5;241m.\u001b[39mvariable, ApplicationExpression(function, argument\u001b[38;5;241m.\u001b[39mterm)\u001b[38;5;241m.\u001b[39msimplify()\n\u001b[1;32m 44\u001b[0m )\n",
"\u001b[0;31mAssertionError\u001b[0m: `{}(\\m.à(donne(exists x.voisin(x)),m))` must be a lambda expression"
]
}
],
"source": [
"# On lit les phrases dans le fichier\n",
"with open('phrases.txt') as f:\n",
" lines = f.readlines()\n",
" \n",
" for phrase in lines:\n",
" # On met tout en minuscule\n",
" phrase = phrase.lower().strip()\n",
" \n",
" # On compte les arbres de dérivation trouvés\n",
" i = len(list(parser.parse(phrase.split())))\n",
" print(i, \"found derivation for sentence:\",phrase)\n",
" g = parser.parse(phrase.split())\n",
" for t in g:\n",
" chart.printCCGDerivation(t)\n",
" \n",
" # On affiche la dérivation la meilleure pour l'arbre\n",
" if (i != 0):\n",
" t,d = bestTree(phrase.split(), lex, rulesC)\n",
" print(\"Best derivation tree has weight\",d)\n",
" chart.printCCGDerivation(t)\n",
" \n",
" print(\"#\"*42)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"? => (S\\S) {\\S.exists x.S(x)}\n",
"attrape => ((S\\N)/N) {\\n m.attrappe(m,n)}\n",
"avec => (((S\\N)\\(S\\N))/N) {\\n V m.V(avec(m,n))}\n",
"chat => pN {chat}\n",
"de => ((N/N)\\N) {\\n m.de(n,m)}\n",
"dents => pN {dents}\n",
"donne => (S\\N) {\\n.donne(n)} | ((S\\N)/N) {\\n m.donne(m,n)} | ((S\\N)\\N) {\\n m.donne(n,m)}\n",
"donner => N {donner} | (N/N) {\\n.donner(n)}\n",
"donné => Pp {\\n.donné(n)}\n",
"dorment => (S\\N) {\\n.dormir(n)}\n",
"dort => (S\\N) {\\n.dormir(n)}\n",
"elle => N {elle}\n",
"est => ((S\\N)/_var10) {\\P x.P(x)} | ((S\\N)/(N/N)) {{}} | ((S\\N)/(N\\N)) {{}}\n",
"et => (((S\\N)/(S\\N))\\(S\\N)) {\\P Q x.(P(x) & Q(x))} | ((N/N)\\N) {\\n m.et(n,m)} | ((S/S)\\S) {\\P Q.(P & Q)}\n",
"fromage => pN {fromage}\n",
"il => N {il}\n",
"la => ((S\\N)/((S\\N)/N)) {\\P n.exists m.P(n,m)} | (N/pN) {\\P.exists x.P(x)}\n",
"le => ((S\\N)/((S\\N)/N)) {\\P n.exists m.P(n,m)} | (N/pN) {\\P.exists x.P(x)}\n",
"lui => ((S\\N)/(S\\N)) {\\V n m.à(V(n),m)}\n",
"mange => (S\\N) {\\n.mange(n)} | ((S\\N)/N) {\\n m.mange(m,n)} | ((S\\N)\\N) {\\n m.mange(n,m)}\n",
"mangé => Pp {\\n.mangé(n)}\n",
"mangée => Pp {\\n.mangé(n)}\n",
"mon => (N/pN) {\\P.exists x.P(x)}\n",
"méchant => (pN/pN) {\\n.méchant(n)} | (pN\\pN) {\\n.méchant(n)}\n",
"noir => (pN\\pN) {\\n.noir(n)} | (pN/pN) {\\n.noir(n)}\n",
"paisiblement => ((S\\N)\\(S\\N)) {\\V n.paisiblement(V(n))}\n",
"par => (((S\\N)\\(S\\N))/N) {\\n V.V(n)}\n",
"pourchasse => ((S\\N)/N) {\\n m.pourchasse(m,n)}\n",
"que => ((N\\N)/S) {{}} | (N/S) {\\x.x}\n",
"quel => (((((S\\N)\\(S\\N))/N)\\(S/S))/N) {{}} | ((S/(S\\N))/N) {\\n V x.V(x,n)}\n",
"quelle => (((((S\\N)\\(S\\N))/N)\\(S/S))/N) {{}} | ((S/(S\\N))/N) {\\n V x.V(x,n)}\n",
"qui => ((N\\N)/(S\\N)) {\\V n.V(n)} | (S/(S\\N)) {\\V x.V(x)}\n",
"quoi => (((S/S)\\(((S\\N)\\(S\\N))/N))/N) {{}}\n",
"rat => pN {rat}\n",
"ses => (N/pN) {\\P.exists x.P(x)}\n",
"souhaite => ((S\\N)/N) {\\N m.souhaite(m,N(m))}\n",
"souris => pN {souris}\n",
"sœur => pN {soeur}\n",
"très => ((pN/pN)/(pN/pN)) {\\P n.très(P(n))}\n",
"un => (N/pN) {\\P.exists x.P(x)}\n",
"voisin => pN {voisin}\n",
"à => (((S\\N)\\(S\\N))/N) {\\n V m.V(à(m,n))}\n"
]
}
],
"source": [
"print(lex)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "venv",
"language": "python",
"name": "venv"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}