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 checkNominalization(concept,roles,env,opts): traceSyntR("checkNominalization", concept) if roles.areEmpty(): if concept in verbalizations and "" in verbalizations[concept]: nominalization=verbalizations[concept][""] return addRoles(nominalization,roles,[],nounInfo(nominalization),env,opts) elif isVerb(concept): verbLemma=re.sub(r"-\d+$","",concept) if verbLemma in morphVerbalizations and "noun" in morphVerbalizations[verbLemma]: nominalization=morphVerbalizations[verbLemma]["noun"] return addRoles(nominalization,roles,[],nounInfo(nominalization),env,opts) else: return None if concept in verbalizations: verbArgs=[key for key in verbalizations[concept].keys() if key!=""] if len(verbArgs)==0:return None for verbArg in verbArgs: if verbArg in roles: subSemR=roles[verbArg] if subSemR.concept in verbalizations[concept][verbArg]: nominalization=verbalizations[concept][verbArg][subSemR.concept] del subSemR.roles[verbArg[2:]] # remove added :ARGi corresponding to the :*:ARGi # splice rest of roles of subSemR into parent roles for rl,sem in subSemR.roles.items(): roles.addRole(rl,sem) del roles[verbArg] return addRoles(nominalization,roles,[],nounInfo(nominalization),env,opts) # process morphVerbalizations if isVerb(concept): verbLemma=re.sub(r"(-\d+)?$",r"",concept) if verbLemma in morphVerbalizations: morphVerb=morphVerbalizations[verbLemma] if ":polarity" in roles: return None #fail if :polarity role is present if ":ARG1" in roles: verbArgs=[key for key in roles.keys() if key!=":ARG1"] if any([isArgOp(arg) for arg in verbArgs]): return None #fail if any :ARGi or :opi is present # OK if :ARG1 is a pronoun that refers to the :ARG0 of the verb of the upper level if roles[":ARG1"].instanceIsRef(): refARG1=roles[":ARG1"].instance instanceRole=refARG1.get_my_role() if ":ARG0" == instanceRole and "noun" in morphVerb: morphVerb=morphVerb["noun"] return addRoles(morphVerb,roles,[":ARG1"],nounInfo(morphVerb),env,opts) # TODO: should check for "actor"... return None
def polarityRole(semR, env, opts): traceSyntR("polarityRole", semR) if unquote(semR.get_instance()) == "-": parent_concept = semR.get_parent_concept() if isVerb(parent_concept): opts.add("typ", {"neg": True}) elif isNoun(parent_concept): env.put(":D", Adv("no")) else: env.unshift(Adv("not")) elif semR.get_concept() == "amr-unknown": opts.add("typ", {"int": "yon"})
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 instance2SyntR(semR): traceSyntR("instance2dsr", semR) instance = semR.instance if isinstance(instance, SemanticRep): myRole = semR.get_my_role() amrRef = instance refRole = amrRef.get_my_role() refConcept = amrRef.get_concept() # print("myRole:%s refRole:%s refConcept:%s"%(myRole,refRole,refConcept)) if isNoun(refConcept) or specialConcept.isSpecialConcept(refConcept): if myRole == ":ARG0" and refRole != None: pronoun = Pro("I") elif myRole == ":ARG1": # is object the same as the subject? parent = semR.get_parent() parentRoles = parent.get_roles() if ":ARG0" in parentRoles and ( parentRoles[":ARG0"] == amrRef or instance == parentRoles[":ARG0"].instance): pronoun = Pro("myself") else: pronoun = Pro("I") else: pronoun = Pro("me") return pronoun.pe(3).g(gender[refConcept] if refConcept in gender else "n") elif isPronoun(refConcept): pronoun = Pro("I") return addOptions(pronoun, pronounOptions[refConcept] ) if refConcept in pronounOptions else pronoun elif isVerb(refConcept): return VP(V(re.sub(r"-\d+$", "", refConcept)).t("b")) else: # clean the referenced concept and quote it return Q(generateConceptWord(refConcept)) elif is_number(instance): return NO(unquote(instance)) elif instance[0] == '"': return Q(unquote(instance)) elif instance in ['-', '+']: return instance else: errorSyntR(instance + " :undefined instance") return Q(instance)
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