mirror of
https://github.com/GrammaticalFramework/comp-syntax-gu-mlt.git
synced 2026-02-09 06:41:07 -07:00
Nobel queries
This commit is contained in:
48
lab2/query/Query.gf
Normal file
48
lab2/query/Query.gf
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
abstract Query = Nobel ** {
|
||||||
|
|
||||||
|
flags startcat = Query ;
|
||||||
|
|
||||||
|
cat
|
||||||
|
Query ;
|
||||||
|
Kind ;
|
||||||
|
Property ;
|
||||||
|
Term ;
|
||||||
|
Element ;
|
||||||
|
|
||||||
|
fun
|
||||||
|
QWhich : Kind -> Property -> Query ; -- which laureates are female
|
||||||
|
QHowMany : Kind -> Property -> Query ; -- how many women are there
|
||||||
|
QWhether : Term -> Property -> Query ; -- is Martti Ahtisaari from Finland
|
||||||
|
QWhat : Element -> Query ; -- who is the youngest laureate
|
||||||
|
|
||||||
|
TAll : Kind -> Term ; -- all laureate
|
||||||
|
TAny : Kind -> Term ; -- any laureate
|
||||||
|
|
||||||
|
KProperty : Property -> Kind -> Kind ; -- female laureate
|
||||||
|
|
||||||
|
ELaureate : Name -> Element ; -- Martti Ahtisaari
|
||||||
|
|
||||||
|
EYoungest : Kind -> Element ; -- the youngest laureate
|
||||||
|
EOldest : Kind -> Element ; -- the oldest laureate
|
||||||
|
|
||||||
|
KMan : Kind ;
|
||||||
|
KWoman : Kind ;
|
||||||
|
|
||||||
|
KLaureate : Kind ;
|
||||||
|
|
||||||
|
KChemistryLaureate : Kind ;
|
||||||
|
KLiteratureLaureate : Kind ;
|
||||||
|
KMedicineLaureate : Kind ;
|
||||||
|
KPeaceLaureate : Kind ;
|
||||||
|
KPhysicsLaureate : Kind ;
|
||||||
|
|
||||||
|
PCountry : Country -> Property ;
|
||||||
|
PBornIn : Date -> Property ;
|
||||||
|
PAwardedIn : Date -> Property ;
|
||||||
|
PMale : Property ;
|
||||||
|
PFemale : Property ;
|
||||||
|
|
||||||
|
BeforeYearDate : Int -> Date ;
|
||||||
|
AfterYearDate : Int -> Date ;
|
||||||
|
|
||||||
|
}
|
||||||
104
lab2/query/QueryEng.gf
Normal file
104
lab2/query/QueryEng.gf
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
--# -path=.:alltenses:../grammars
|
||||||
|
|
||||||
|
concrete QueryEng of Query = NobelEng **
|
||||||
|
|
||||||
|
open
|
||||||
|
SyntaxEng, ParadigmsEng,
|
||||||
|
SymbolicEng,
|
||||||
|
(G = GrammarEng),
|
||||||
|
(M = MakeStructuralEng),
|
||||||
|
Prelude
|
||||||
|
in {
|
||||||
|
|
||||||
|
lincat
|
||||||
|
Query = Utt ;
|
||||||
|
Kind = CN ;
|
||||||
|
Property = {ap : AP ; adv : Adv ; isAdv : Bool} ;
|
||||||
|
Term = NP ;
|
||||||
|
Element = NP ;
|
||||||
|
|
||||||
|
lin
|
||||||
|
QWhich kind property =
|
||||||
|
mkUtt (mkQS tenses (mkQCl (mkIP whichPl_IDet kind) (propertyVP property)))
|
||||||
|
| mkUtt (mkNP aPl_Det (propertyCN property kind))
|
||||||
|
;
|
||||||
|
|
||||||
|
QHowMany kind property =
|
||||||
|
mkUtt (mkQS tenses (mkQCl (mkIP how8many_IDet kind) (propertyVP property)))
|
||||||
|
| mkUtt (mkIP how8many_IDet (propertyCN property kind))
|
||||||
|
;
|
||||||
|
|
||||||
|
QWhether term property =
|
||||||
|
mkUtt (mkQS tenses (mkQCl (mkCl term (propertyVP property))))
|
||||||
|
;
|
||||||
|
|
||||||
|
QWhat element =
|
||||||
|
mkUtt (mkQS tenses (mkQCl who_IP element)) -- what is 2 + 2
|
||||||
|
| mkUtt element -- 2 + 2
|
||||||
|
;
|
||||||
|
|
||||||
|
TAll kind =
|
||||||
|
mkNP all_Predet (mkNP aPl_Det kind) -- all numbers
|
||||||
|
| mkNP every_Det kind -- every number
|
||||||
|
;
|
||||||
|
|
||||||
|
TAny kind =
|
||||||
|
mkNP someSg_Det kind -- some number
|
||||||
|
| mkNP somePl_Det kind -- some numbers
|
||||||
|
| mkNP (M.mkDet "any" singular) kind -- any number
|
||||||
|
| mkNP (M.mkDet "any" plural) kind -- any numbers
|
||||||
|
;
|
||||||
|
|
||||||
|
KProperty property kind = propertyCN property kind ;
|
||||||
|
|
||||||
|
ELaureate name = name ;
|
||||||
|
|
||||||
|
EYoungest kind = mkNP (mkDet the_Quant (SyntaxEng.mkOrd (mkA "young" "younger"))) kind ;
|
||||||
|
EOldest kind = mkNP (mkDet the_Quant (SyntaxEng.mkOrd (mkA "old"))) kind ;
|
||||||
|
|
||||||
|
KMan = mkCN (mkN "man" "men") ;
|
||||||
|
KWoman = mkCN (mkN "woman" "women") ;
|
||||||
|
|
||||||
|
KLaureate = mkCN (mkN "laureate") | mkCN (mkN "Nobel prize laureate") ;
|
||||||
|
|
||||||
|
KChemistryLaureate = mkCN (mkN "chemistry laureate") ;
|
||||||
|
KLiteratureLaureate = mkCN (mkN "literature laureate") ;
|
||||||
|
KMedicineLaureate = mkCN (mkN "medicine laureate") ;
|
||||||
|
KPeaceLaureate = mkCN (mkN "peace laureate") ;
|
||||||
|
KPhysicsLaureate = mkCN (mkN "physics laureate") ;
|
||||||
|
|
||||||
|
PCountry country = mkProperty (SyntaxEng.mkAdv from_Prep country) ;
|
||||||
|
PBornIn date = mkProperty (G.AdvAP (mkAP (mkA "born")) date) ;
|
||||||
|
PAwardedIn date = mkProperty date ;
|
||||||
|
|
||||||
|
PMale = mkProperty "male" ;
|
||||||
|
PFemale = mkProperty "female" ;
|
||||||
|
|
||||||
|
BeforeYearDate y = SyntaxEng.mkAdv before_Prep <symb y : NP> ;
|
||||||
|
AfterYearDate y = SyntaxEng.mkAdv after_Prep <symb y : NP> ;
|
||||||
|
|
||||||
|
oper
|
||||||
|
tenses = presentTense | pastTense ;
|
||||||
|
|
||||||
|
mkProperty = overload {
|
||||||
|
mkProperty : Str -> Property = \s ->
|
||||||
|
lin Property {ap = mkAP (mkA s) ; adv = ParadigmsEng.mkAdv "" ; isAdv = False} ;
|
||||||
|
mkProperty : AP -> Property = \ap ->
|
||||||
|
lin Property {ap = ap ; adv = ParadigmsEng.mkAdv "" ; isAdv = False} ;
|
||||||
|
mkProperty : Adv -> Property = \adv ->
|
||||||
|
lin Property {ap = mkAP (mkA "") ; adv = adv ; isAdv = True} ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
propertyCN : {ap : AP ; adv : Adv ; isAdv : Bool} -> CN -> CN = \prop, cn ->
|
||||||
|
case prop.isAdv of {
|
||||||
|
True => mkCN cn prop.adv ;
|
||||||
|
False => mkCN prop.ap cn
|
||||||
|
} ;
|
||||||
|
|
||||||
|
propertyVP : {ap : AP ; adv : Adv ; isAdv : Bool} -> VP = \prop ->
|
||||||
|
case prop.isAdv of {
|
||||||
|
True => mkVP prop.adv ;
|
||||||
|
False => mkVP prop.ap
|
||||||
|
} ;
|
||||||
|
|
||||||
|
}
|
||||||
113
lab2/query/query.py
Normal file
113
lab2/query/query.py
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import pgf
|
||||||
|
|
||||||
|
# we assume this abstract syntax
|
||||||
|
ABSMODULE = "Query"
|
||||||
|
|
||||||
|
# data file with laureates
|
||||||
|
DATAFILE = '../data/query.json'
|
||||||
|
|
||||||
|
WIKIDATA_PREFIX = 'http://www.wikidata.org/entity/'
|
||||||
|
|
||||||
|
# the domain of quantification is the list of laureates with their properties, built from the query result
|
||||||
|
with open(DATAFILE) as file:
|
||||||
|
data = json.load(file)
|
||||||
|
|
||||||
|
|
||||||
|
def listNames(ds):
|
||||||
|
return [d['personLabel'] for d in ds]
|
||||||
|
|
||||||
|
|
||||||
|
def funQID(fun):
|
||||||
|
return WIKIDATA_PREFIX + str(fun).split('_')[0]
|
||||||
|
|
||||||
|
def age(d):
|
||||||
|
return int(d['date'][:4]) - int(d['birthDate'][:4])
|
||||||
|
|
||||||
|
|
||||||
|
def answer(tree):
|
||||||
|
"top level Query interpreter"
|
||||||
|
|
||||||
|
match tree.unpack():
|
||||||
|
case ("QWhich", [kind, property]):
|
||||||
|
return listNames([x for x in data if predicate(kind)(x) and predicate(property)(x)])
|
||||||
|
case ("QHowMany", [kind, property]):
|
||||||
|
return len([x for x in data if predicate(kind)(x) and predicate(property)(x)])
|
||||||
|
case ( "QWhether", [term, property]):
|
||||||
|
return quantifier(term)(predicate(property))
|
||||||
|
case ( "QWhat", [element]):
|
||||||
|
return value(element)
|
||||||
|
|
||||||
|
print('not yet', str(tree))
|
||||||
|
|
||||||
|
|
||||||
|
def predicate(tree):
|
||||||
|
"takes Property or Kind to int -> bool"
|
||||||
|
|
||||||
|
match tree.unpack():
|
||||||
|
case ("PCountry", [fun]):
|
||||||
|
return lambda d: d['country'] == funQID(fun)
|
||||||
|
case ("PMale", []):
|
||||||
|
return lambda d: d['sexLabel'] == 'male'
|
||||||
|
case ("PFemale", []):
|
||||||
|
return lambda d: d['sexLabel'] == 'female'
|
||||||
|
case ("KProperty", [property, kind]):
|
||||||
|
return lambda d: predicate(property)(d) and predicate(kind(d))
|
||||||
|
case ("KLaureate", []):
|
||||||
|
return lambda d: True
|
||||||
|
case ("KMan", []):
|
||||||
|
return lambda d: d['sexLabel'] == 'male'
|
||||||
|
case ("KWoman", []):
|
||||||
|
return lambda d: d['sexLabel'] == 'female'
|
||||||
|
|
||||||
|
print('not yet', str(tree))
|
||||||
|
|
||||||
|
|
||||||
|
def quantifier(term):
|
||||||
|
"takes Term to (int -> bool) -> bool"
|
||||||
|
match term.unpack():
|
||||||
|
case ("TElement", element):
|
||||||
|
return lambda p: p(value(element))
|
||||||
|
case ("TAll", [kind]):
|
||||||
|
return lambda p: all(lambda x: not predicate(kind)(x) or p(x), data)
|
||||||
|
case ("TAny", [kind]):
|
||||||
|
return lambda p: any(lambda x: predicate(kind)(x) and p(x), data)
|
||||||
|
|
||||||
|
print('not yet', str(tree))
|
||||||
|
|
||||||
|
|
||||||
|
def value(element):
|
||||||
|
"takes Element to a laureate record"
|
||||||
|
|
||||||
|
match element.unpack():
|
||||||
|
case ('ELaureate', [name]):
|
||||||
|
_, string = name.unpack
|
||||||
|
return [d for d in data if d['personLabel'] == string][0] ## uncertain !
|
||||||
|
case ('EYoungest', [kind]):
|
||||||
|
return min(data, key = age)
|
||||||
|
case ('EOldest', [kind]):
|
||||||
|
return max(data, key = age)
|
||||||
|
|
||||||
|
print('not yet', str(tree))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"main function to be called from stdio, language code as optional argument"
|
||||||
|
|
||||||
|
# read in the grammar, set up the input language
|
||||||
|
grammar = pgf.readPGF(ABSMODULE + ".pgf")
|
||||||
|
LANG = ABSMODULE + sys.argv[1]
|
||||||
|
lang = grammar.languages[LANG]
|
||||||
|
|
||||||
|
# read a line of input, parse in lang, return answer
|
||||||
|
line = input("")
|
||||||
|
parseresult = lang.parse(line)
|
||||||
|
prob,tree = parseresult.__next__()
|
||||||
|
print('#', tree) ## debugging
|
||||||
|
print(answer(tree))
|
||||||
|
for r in parseresult:
|
||||||
|
print("WARNING: ambiguous")
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user