def jsrTemp(val, lang): if val == 0: return N("zero") if lang == "en" else N("zéro") if val < 0: return AdvP(A("minus") if lang == "en" else Adv("moins"), NO(abs(val))) if val <= 5: return AP(A("plus"), NO(val)) if lang == "en" else AdvP( Adv("plus"), NO(val)) return NO(val)
def makeSyntR(semR, checkSpecial=True): # checkSpecial is False when called from within specialConcept.checkSpecialConcept # to avoid infinite loop traceSyntR("makeSyntR", semR) concept = semR.concept if concept == None: # l'instance réfère à un autre AMR return instance2SyntR(semR) if checkSpecial: sConcept = specialConcept.checkSpecialConcept(semR) if sConcept != None: traceSyntR("special concept", concept) return sConcept # evaluate each role to build the environment dictInfo = getSyntR(concept) env = Env() opts = Options() roles = semR.get_roles() if isVerb(concept): #only for verbs # HACK for passive : seem to be too aggressive.... so we keep it only for top-level AMR # generate a passive sentence if concept has an :ARG0 and the actual roles does not have :ARG0 but has :ARG1 # %% do not passivate the special case of bear-02 because it is already passive if concept!="bear-02" and semR.parent==None and \ ":ARG0" in verbs[concept].args and ":ARG0" not in semR.roles and ":ARG1" in semR.roles: opts.add("typ", {"pas": True}) roleProcessing.processRoles(concept, roles, [], dictInfo, env, opts) ## patch the syntactic structures for frequent special cases if isVerb(concept): # HACK for changing nominative pronoun to accusative for :ARG1 when :ARG0 is also present if ":ARG1" in env and ":ARG0" in env and isinstance( env[":ARG1"], Pro) and env[":ARG1"].lemma == "I": env[":ARG1"].lemma = "me" elif isAdjective(concept): # adjective with :ARG0 and :ARG1 adj = dictInfo.lemma if ":ARG0" in env and ":ARG1" in env: if isinstance(env[":ARG0"], Pro) and env[":ARG0"].lemma == "me": env[":ARG0"].lemma = "I" if isinstance(env[":ARG1"], Pro) and env[":ARG1"].lemma == "I": env[":ARG0"].lemma = "me" dictInfo = LexSem( adj, "S", [":ARG0", ":ARG1"], lambda arg0, arg1: S( arg0, VP(V("be"), A(adj), pp("for", arg1)))) elif ":ARG1" in env and ":ARG2" in env: if isinstance(env[":ARG1"], Pro) and env[":ARG1"].lemma == "me": env[":ARG1"].lemma = "I" if isinstance(env[":ARG2"], Pro) and env[":ARG2"].lemma == "I": env[":ARG2"].lemma = "me" dictInfo = LexSem( adj, "S", [":ARG1", ":ARG2"], lambda arg1, arg2: S( arg1, VP(V("be"), A(adj), pp("for", arg2)))) elif ":ARG1" in env: if isinstance(env[":ARG1"], Pro) and env[":ARG1"].lemma == "me": env[":ARG1"].lemma = "I" dictInfo = LexSem(adj, "S", [":ARG1"], lambda arg1: S(arg1, VP(V("be"), A(adj)))) syntR = dictInfo.apply(env, opts) return syntR
def makeA(lemma): adj=adjectives[lemma] if isinstance(adj,LexSem): return adj if isinstance(adj,AP): return LexSem(lemma,"A",[":ARG1"],lambda arg1:copy.deepcopy(adj).add(arg1)) if isinstance(adj,A): return LexSem(lemma,"A",[":ARG1"],lambda arg1:AP(copy.deepcopy(adj),arg1)) if isinstance(adj,str): return LexSem(lemma,"A",[":ARG1"],lambda arg1:A(adj) if arg1==None else AP(A(adj),arg1)) print("### strange adjective:"+str(adj)) return adj
def ageRole(semR, env, opts): traceSyntR("ageRole", semR) if semR.get_concept() == "amr-unknown": env.unshift(Q("how old")) opts.add("a", "?") else: env.push(makeSyntR(semR).lier()) env.push(A("old"))
def modal(concept,roles,env,opts): traceSyntR("modal",concept) (adj,arg,option,t)=modals[concept] # print("roles:"+str(roles)) if arg not in roles: return A(adj) argSyntR=makeSyntR(roles[arg]) opts.add("t",t) opts.add("typ",{"mod":option}) return addRoles(concept,roles,[arg],LexSem("modal","S",[],lambda:argSyntR),env,opts)
def conditionRole(semR, env, opts): traceSyntR("conditionRole", semR) concept = semR.get_concept() if concept == "as-long-as": roles = semR.get_roles() if ":op1" in roles: env.push(PP(P("as"), A("long"), P("as"), makeSyntR(roles[":op1"]))) return if concept == "otherwise": env.push(SP(C("otherwise"), makeSyntR(semR))) else: env.push(SP(C("if"), makeSyntR(semR)))
def governmentOrganization(concept,roles,env,opts): traceSyntR("governmentOrganization", concept) if ":*:ARG0" in roles: if roles[":*:ARG0"].get_concept()=="govern-01": starArg0Roles=roles[":*:ARG0"].roles if len(roles)==1: return addRoles(concept, starArg0Roles, [":ARG0"], nounInfo("government"), env, opts) elif ":ARG1" in starArg0Roles: dictInfo=nounInfo("government") env.push(PP(P("of"),makeSyntR(starArg0Roles[":ARG1"]))) return addRoles(concept, starArg0Roles,[":ARG0",":ARG1"], dictInfo, env, opts) dictInfo=nounInfo("organization") env.put(":A",A("governmental")) return addRoles(concept, roles, [":*:ARG0"], dictInfo, env, opts)
def processTime(concept, syntR): if concept == "amr-unknown": opts.add("typ", {"int": "whn"}) env.push(syntR) elif syntR == A("former"): env.unshift(Adv("formerly")) elif syntR == Q("ex"): env.unshift(syntR) elif syntR == Q("about to"): env.push(Adv("about")) env.push(P("to")) elif isVerb(concept): env.push(SP(C("when"), syntR)) elif isinstance(syntR, A): env.push(Adv(adverbFromAdjective(syntR.lemma))) else: env.push(syntR)
def title_block(wInfo, lang): issueDate = wInfo.get_issue_date() noSecond = {"second": False} if lang == "en": s1 = S( NP(N("forecast").n("p")), VP( V("issue").t("pp"), PP( P("by"), Q("jsRealB"), DT(issueDate).dOpt(noSecond), P("for"), CP( C("and"), N("today"), DT(issueDate + datetime.timedelta(days=1)).dOpt( {"rtime": issueDate}))))) s2 = S( NP(D("the"), D("next"), V("schedule").t("pp"), N("forecast").n("p")), VP( V("be").t("f"), V("issue").t("pp"), DT(wInfo.get_next_issue_date()).dOpt(noSecond))) else: s1 = S( NP(N("prévision").n("p")), VP( V("émettre").t("pp"), PP( P("par"), Q("jsRealB"), DT(issueDate).dOpt(noSecond), P("pour"), CP( C("et"), Adv("aujourd'hui"), DT(issueDate + datetime.timedelta(days=1)).dOpt( {"rtime": issueDate}))))) s2 = S( NP(D("le"), A("prochain").pos("pre"), N("prévision").n("p")), VP( V("être").t("f"), V("émettre").t("pp"), DT(wInfo.get_next_issue_date()).dOpt(noSecond))) return "\n".join([realize(s1, lang, False), realize(s2, lang, False)])
def degreeRole(semR, env, opts): traceSyntR("degreeRole", semR) global comp comp = "" deg = semR.get_concept() if deg == "amr-unknown": opts.add("b", "how ") elif deg == "more": opts.add("f", "co") comp = "co" elif deg == "most": opts.add("f", "su") comp = "su" elif deg == "part": env.unshift(Adv("partially")) elif deg in ["too", "so", "very", "all", "quite"]: env.unshift(Adv(deg)) elif isAdverb(deg): env.push(Adv(deg)) elif isAdjective(deg): env.push(A(deg)) else: env.push(makeSyntR(semR))
def simpleModNoun(concept, neg): ## check for "simple" cases if concept in [ "all", "many", "both", "no", "too", "any", "other", "some", "one", "kind-yy", "then", "such" ]: env.put(":D", Q("kind of" if concept == "kind-yy" else concept)) if neg: env.unshift(Q("not")) if concept in ["all", "many", "both"]: opts.add("n", "p") elif concept in determiners: env.put(":D", D(concept)) elif is_number(concept): env.push(NO(concept)) elif isNoun(concept): ## prefix the :mod for nouns newNoun = N(nouns[concept].lemma) # keep only noun from NP if ":A" in env: env.insertAfter(":A", ":A", newNoun) else: env.put(":A", newNoun) if neg: env.insertBefore(":A", ":A", Q("non")) elif isAdjective(concept): ## postfix the :mod for adjectives newAdj = A(adjectives[concept].lemma) if ":A" in env: env.insertAfter(":A", ":A", newAdj) else: env.put(":A", newAdj) if neg: env.insertBefore(":A", ":A", Q("non")) elif isAdverb(concept): env.put(":D", Adv(concept)) elif isVerb(concept): env.push(V(re.sub(r"-\d+$", '', concept)).t("pr")) elif semR.roles.areEmpty(): ## equivalent to processSimpleModOther env.push(Q(generateConceptWord(concept))) else: return False return True
from jsRealBclass import N,A,Adv,V,D,P,C,DT,NO,Q, NP,AP,AdvP,VP,S,PP,CP from Realization.common import realize, jsrDayPeriod sky_condition_terminology = { ## types of sky conditions "c1":{"en":(AP(A("sunny")),AP(A("clear"))), "fr":(AP(A("ensoleillé")),AP(A("dégagé")))}, "c2":{"en":(AP(Adv("mainly"),A("sunny")),NP(Q("a"),D("few"),N("cloud").n("p"))), "fr":(AP(Adv("généralement"),A("ensoleillé")),NP(D("quelque"),N("nuage").n("p")))}, "c3":{"en":(NP(D("a"),N("mix"),PP(P("of"),CP(C("and"),N("sun"),N("cloud").n("p")))), AP(Adv("partly"),A("cloudy"))), "fr":(NP(N("alternance"),CP(C("et"),PP(P("de"),N("soleil")),PP(P("de"),N("nuage").n("p")))), AP(Adv("partiellement"),A("couvert")))}, "c4":{"en":(AP(Adv("mainly"),A("cloudy")),), "fr":(AP(Adv("généralement"),A("nuageux")),)}, "c5":{"en":(AP(A("cloudy")),), "fr":(AP(A("nuageux")),)}, "c6":{"en":(AP(A("overcast")),), "fr":(AP(A("couvert")),)}, "c7":{"en":(NP(V("increase").t("pr"),N("cloudiness")),), "fr":(NP(N("ennuagement")),)}, "c8":{"en":(NP(N("clearing")),), "fr":(NP(N("dégagement")),)}, } def sky_condition(mc,period,lang): previous_conditions=[] jsrExprs=[] def addNoRepeat(c,dn,period=None): # avoid generating same sentence twice if c not in previous_conditions: if len(sky_condition_terminology[c][lang])==1:dn=0
P("en"), N("matinée"))) }, "b": { "en": lambda t, u: S( Adv("low"), u.a(","), P("with"), temp_trend("en", "rise", t, PP(P("by"), N("morning")))), "fr": lambda t, u: S( N("minimum"), u.a(","), temp_trend("fr", "hausse", t, PP(P("en"), N("matinée")))) }, "c": { "en": lambda t, p: temp_trend("en", "rise", t, p).add( AdvP(Adv("then"), A("steady"))), "fr": lambda t, p: temp_trend("fr", "hausse", t, p).add( PP(P("pour"), Adv("ensuite"), V("demeurer").t("b"), A("stable"))) }, "d": { "en": lambda t, p: temp_trend("en", "rise", t, p).add( AdvP(Adv("then"), V("rise").t("pr"), Adv("slowly"))), "fr": lambda t, p: temp_trend("fr", "hausse", t, p).add( AdvP(Adv("puis"), NP(N("hausse"), A("graduel")))) }, "e": {
def showSyntR(syntR): print(syntR.show()) # show the indented structure print(jsRealB(syntR.show(-1))) # get realized string ## a few lexicon entries verbs={} nouns={} verbs['give-01']=LexSem("V","give",[":ARG0",":ARG1",":ARG2"], lambda arg0,arg1,arg2:S(arg0,VP(V("give"),arg1,pp("to",arg2)))) nouns['envelope'] = LexSem("envelope","N",[":D",":A"],lambda d,a:NP(optD(d),a,N("envelope"))) nouns['boy'] = LexSem("boy","N",[":D",":A"],lambda d,a:NP(optD(d),a,N("boy"))) nouns['girl'] = LexSem("girl","N",[":D",":A"],lambda d,a:NP(optD(d),a,N("girl"))) boyEnv=Env([(':D',D("a"))]) boyEnv.put(":A",A("nice")).put(":A",A("little")) boySyntR=nouns["boy"].apply(boyEnv,Options([("n","p")])) showSyntR(boySyntR) # NP(D("a"), # A("nice"), # A("little"), # N("boy")).n("p") # nice little boys envelope=nouns["envelope"] envelopeSyntR=envelope.apply() showSyntR(envelopeSyntR) # NP(D("the"), # N("envelope")) # the envelope
# ARG0:giver / ARG1:thing given / ARG2:entity given to [give.xml] verbs['give-01']=LexSem("give","V",[":ARG0",":ARG1",":ARG2"], lambda arg0,arg1,arg2:S(arg0,VP(V("give"),arg1,pp("to",arg2)))) verbs['know-01']=LexSem("know","V",[":ARG0",":ARG1",":ARG2"], # strangely the lemma is "idk" in PropBank lambda arg0,arg1,arg2:S(arg0,VP(V("know"),arg1,pp("to",arg2)))) ## in PropBank : bear-02 :ARG0 should be the "bearer" (e.g. the mother) and :ARG1 the "bearee" ## but in AMR, :ARG1 is used as the person who is born... without :ARG0 verbs['bear-02']=LexSem("born","V",[":ARG0",":ARG1"], lambda arg0,arg1:S(arg1,VP(V("be"),V("born").t("pp"),pp("to",arg0)))) ## in PropBank: hunger-01 :ARG0 corresponds to the person who is hungry (hunger is archaic in this acception) ## so we translate with a more colloquial "be hungry [for...]" verbs['hunger-01']=LexSem("hunger","V",[":ARG0",":ARG1"], lambda arg0,arg1:S(arg0,VP(V("be"),A("hungry"),pp("for",arg1)))) ## correction of prepositions... # ARG0:buyer / ARG1:thing bought / ARG2:seller / ARG3:price paid / ARG4:benefactive [buy.xml] verbs['buy-01']=LexSem("buy","V",[":ARG0",":ARG1",":ARG2",":ARG3",":ARG4"], lambda arg0,arg1,arg2,arg3,arg4:S(arg0,VP(V("buy"),arg1,pp("from",arg2),pp("at",arg3),pp("for",arg4)))) # ARG0:assessor of not failing / ARG1:thing failing / ARG2:task / ARG3:benefactive [fail.xml] verbs['fail-01']=LexSem("fail","V",[":ARG0",":ARG1",":ARG2",":ARG3"], lambda arg0,arg1,arg2,arg3:S(arg0,arg1,VP(V("fail"),pp("to",arg2),pp("on",arg3)))) # ARG0:pilot, agentive entity capable of flight (like a bird) / ARG1:passenger, cargo / ARG2:aircraft flown, flight number, steed, non-agentive thing in motion / ARG3:type of flight plan, mission, cognate object (like 'a flight' or 'sorties') / ARG4:airline [fly.xml] verbs['fly-01'] = LexSem("V","fly",[":ARG0",":ARG1",":ARG2",":ARG3",":ARG4"], lambda arg0,arg1,arg2,arg3,arg4:S(arg0,arg1,arg2,VP(V("fly"),arg3,pp("by",arg4)))) ## ARG1 <=> ARG2 because of bad parsing of Propbank
"en": Adv("west"), "fr": NP(D("le"), N("ouest")), "deg": 290 }, "ely": { "en": Adv("easterly"), "fr": NP(D("le"), N("secteur"), N("est")), "deg": 90 }, "nly": { "en": Adv("northerly"), "fr": NP(D("le"), N("secteur"), N("nord")), "deg": 0 }, "nely": { "en": A("northeasterly"), "fr": NP(D("le"), N("secteur"), N("nord-est")), "deg": 45 }, "nwly": { "en": A("northwesterly"), "fr": NP(D("le"), N("secteur"), N("nord-ouest")), "deg": 315 }, "wly": { "en": Adv("westerly"), "fr": NP(D("le"), N("secteur"), N("ouest")), "deg": 270 }, "sly": { "en": Adv("southerly"),
pp = lambda prep, arg: PP(P(prep), arg) if arg != None else None optD = lambda det: det if det != None else D("the") verbs['give-01'] = LexSem( "V", "give", [":ARG0", ":ARG1", ":ARG2"], lambda arg0, arg1, arg2: S(arg0, VP(V("give"), arg1, pp("to", arg2)))) nouns['envelope'] = LexSem("envelope", "N", [":D", ":A"], lambda d, a: NP(optD(d), a, N("envelope"))) nouns['boy'] = LexSem("boy", "N", [":D", ":A"], lambda d, a: NP(optD(d), a, N("boy"))) nouns['girl'] = LexSem("girl", "N", [":D", ":A"], lambda d, a: NP(optD(d), a, N("girl"))) adjectives["little"] = LexSem("little", "A", [], lambda: A("little")) adjectives["nice"] = LexSem("nice", "A", [], lambda: A("nice")) nounInfo = lambda lemma: LexSem(lemma, "N", [":D", ":A"], lambda d, a: NP( optD(d), a, N(lemma))) adjInfo = lambda lemma: LexSem(lemma, "A", [], lambda: A(lemma)) def showSyntR(syntR): print(syntR) print(syntR.show()) print(jsRealB(syntR.show(-1))) def op16(conj): return LexSem(
self.opts.append((opt, value)) else: self.opts.append((opt, value)) return self def apply(self, syntR): for opt, value in self.opts: # adapted from https://stackoverflow.com/questions/3061/calling-a-function-of-a-module-by-using-its-name-a-string getattr(syntR, opt)(value) return syntR nounInfo = lambda lemma: LexSem(lemma, "N", [":D", ":A"], lambda d, a: NP( optD(d), a, N(lemma))) adjInfo = lambda lemma: LexSem( lemma, "A", [":ARG1"], lambda a1: A(lemma) if a1 == None else AP(A(lemma), a1)) pp = lambda prep, arg: PP(P(prep), arg) if arg != None else None optD = lambda det: det if det != None else D("the") class LexSem: def __init__(self, lemma, pos, args, lambda_): self.lemma = lemma self.pos = pos self.args = args self.lambda_ = lambda_ def __str__(self): return "LexSem(%s,%s)" % (self.lemma, self.pos)
from jsRealBclass import jsRealB, N,A,Adv,V,D,P,C,DT,NO,Q, NP,AP,AdvP,VP,S,SP,PP,CP from Realization.common import realize, jsrDayPeriod, jsrHour, get_max_term, get_min_term, get_term_at precipitationTypes = { "showers":{"en":N("shower").n("p"), "fr":N("averse").n("p")}, "flurries":{"en":N("flurry").n("p"), "fr":NP(N("averse").n("p"),PP(P("de"),N("neige")))}, "wet-flurries":{"en":NP(A("wet"),N("flurry").n("p")), "fr":NP(N("averse").n("p"),PP(P("de"),N("neige"),A("fondant")))}, "blizzard":{"en":N("blizzard"), "fr":N("blizzard")}, "snow-squalls":{"en":NP(N("snow"),N("squall").n("p")), "fr":NP(N("bourrasque").n("p"),PP(P("de"),N("neige")))}, "drizzle":{"en":N("drizzle"), "fr":N("bruine")}, "freezing-drizzle" :{"en":NP(V("freeze").t("pr"),N("drizzle")), "fr":NP(N("bruine"),A("verglaçant"))}, "ice-crystals" :{"en":NP(N("ice"),N("crystal").n("p")), "fr":NP(N("cristal").n("p"),PP(P("de"),N("glace")))}, "hail":{"en":N("hail"), "fr":N("grêle")}, "ice-pellets":{"en":NP(N("ice"),N("pellet").n("p")), "fr":N("grésil")}, "snow":{"en":N("snow"), "fr":N("neige")}, "wet-snow" :{"en":NP(A("wet"),N("snow")), "fr":NP(N("neige"),N("fondant"))}, "thunderstorm":{"en":N("thunderstorm"), "fr":N("orage").n("p")}, "rain":{"en":N("rain"),
from jsRealBclass import jsRealB, N,A,Adv,V,D,P,C,DT,NO,Q, NP,AP,AdvP,VP,S,PP,CP from Realization.common import realize, jsrDayPeriod, jsrHour, get_max_term, get_min_term, get_term_at #### UV_index values: info taken from # https://www.canada.ca/en/environment-climate-change/services/weather-health/uv-index-sun-safety/about.html # Low (0-2), Moderate (3-5), High (6-7), Very High (8-10), and Extreme (11+) uv_ranges= [(2, {"en":A("low"), "fr":A("bas")}), (5, {"en":A("moderate"), "fr":A("modéré")}), (7, {"en":A("high"), "fr":A("élevé")}), (10, {"en":AP(Adv("very"), A("high")), "fr":AP(Adv("très"),A("élevé"))}), (1000,{"en":A("extreme"), "fr":A("extrême")})] def uv_index(wInfo,period,lang): if period in ["tonight","tomorrow_night"]: # no UV index during the night return None uvi_terms=wInfo.get_uv_index(period) if uvi_terms==None:return None uvVal=uvi_terms[0].infos[0] # consider only the first uvi_term if uvVal<1: return None # too low uvVal=round(uvVal) if uvVal==0:return None for high,expr in uv_ranges: if uvVal<=high: return realize(NP(Q("UV index" if lang=="en" else "indice UV"), NO(uvVal),C("or" if lang=="en" else "ou"),expr[lang]), lang) return None if __name__ == '__main__': def showEnFr(jsrExprEN,jsrExprFR):