Пример #1
0
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)
Пример #2
0
def havePolarity91(concept,roles,env,opts):
    if ":ARG2" in roles:
        pol=unquote(roles[":ARG2"].get_instance())
        if  pol=='-':
            env.push(AdvP(Adv("not")))
        elif pol =='+':
            env.push(AdvP(Adv("yes")))
        return addRoles(concept, roles, [":ARG2"], LexSem("polarity","SP",[],lambda:SP()), env, opts)
    return None
Пример #3
0
def temperature(wInfo, period, lang):
    temperature_terms = wInfo.get_temperature(period)
    if temperature_terms == None: return None
    maxTemp = get_max_term(temperature_terms, 0).infos[0]
    minTemp = get_min_term(temperature_terms, 0).infos[0]
    dn = "night" if period in ["tonight", "tomorrow_night"] else "day"
    tempVals = wInfo.get_temperature_values(period)
    periodName = periodNames[period][lang](wInfo.get_issue_date())
    # checking for an abnormal temperature trend, either
    #     positive change of least 3°C during the night
    #     negative change of last 3°C during the day
    (t1,t2,i1)=(maxTemp,minTemp,tempVals.index(minTemp)) if dn=="night" else\
               (minTemp,maxTemp,tempVals.index(maxTemp))
    # print("dn=",dn,"t1=",t1,"t2=",t2)
    if t1 >= t2 + 3:  # abnormal change time
        if i1 <= 1:
            return realize(jsrAbnormal[dn]["a"][lang](t1, periodName), lang,
                           False)
        else:
            if i1 < 6:  # abnormality occurs during the first 6 hours of the period
                rest = tempVals[i1:]
                if all([abs(t - t1) <= 2 for t in rest]):
                    # c) remains +/- 2 for the rest of the period
                    return realize(jsrAbnormal[dn]["c"][lang](t1, periodName),
                                   lang, False)
                elif any([t - t1 > 2 for t in rest]):
                    # d) rises more than 2 for the rest
                    return realize(jsrAbnormal[dn]["d"][lang](t1, periodName),
                                   lang, False)
                elif any([t1 - t > 2 for t in rest]):
                    # e) falls more than 2 for the rest (this should never happen!!!)
                    return realize(jsrAbnormal[dn]["e"][lang](t1, periodName),
                                   lang, False)
            else:
                # b) low temperature after the beginning (but no special case)

                return realize(
                    jsrAbnormal[dn]["b"][lang](t1, jsrTemp(t2, lang)), lang,
                    False)
    # normal case
    res = []
    if lang == "en":  # output maximum temperature
        res.append(realize(S(Adv("high"), jsrTemp(maxTemp, "en")), "en",
                           False))
    else:
        res.append(
            realize(S(N("maximum"), jsrTemp(maxTemp, "fr")), "fr", False))
    if minTemp < maxTemp - 2:  # output minimum if it differs significantly from the maximum
        if lang == "en":
            res.append(
                realize(S(Adv("low"), jsrTemp(minTemp, "en")), "en", False))
        else:
            res.append(
                realize(S(N("minimum"), jsrTemp(minTemp, "fr")), "fr", False))
    return " ".join(res)
Пример #4
0
def liRole(semR, env, opts):
    traceSyntR("liRole", semR)
    semR_i = unquote(semR.get_instance())
    if semR_i == "-1":
        env.unshift(Adv("lastly"))
    elif semR_i == "1":
        env.unshift(Adv("first"))
    elif is_number(semR_i):
        env.unshift(Q("(" + str(semR_i) + ")"))
    elif semR_i[0] == '"':
        env.unshift(Q("(" + semR_i + ")"))
Пример #5
0
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"})
Пример #6
0
def mannerRole(semR, env, opts):
    traceSyntR("mannerRole", semR)
    cManner = semR.get_concept()
    if cManner == "amr-unknown":
        opts.add("typ", {"int": "how"})
    else:
        syntR = makeSyntR(semR)
        if isinstance(syntR, Q):
            env.push(syntR)
        elif isinstance(syntR, A):
            adv = Adv(adverbFromAdjective(syntR.lemma))
            adv.props = syntR.props
            env.push(adv)
        elif isinstance(syntR, (S, V, VP)):
            env.push(PP(P("by"), syntR.typ({"prog": True})))
        else:
            addPrep("with", semR, env)
Пример #7
0
 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)
Пример #8
0
def ensurePhrase(syntR):
    if isinstance(syntR, Phrase): return syntR
    if isinstance(syntR, Terminal):
        if isinstance(syntR, N): return NP(syntR)
        if isinstance(syntR, A): return AP(syntR)
        if isinstance(syntR, V): return VP(syntR)
        if isinstance(syntR, Adv): return Adv(syntR)
        return SP(syntR)
    print("ensurePhrase: type inattendu:%s" % type(syntR))
Пример #9
0
def makeAdv(lemma):
    adv=adverbs[lemma]
    if isinstance(adv,AdvP):
        return LexSem(lemma,"Adv",[":op1"],lambda op1:copy.deepcopy(adv).add(accPron(op1)))
    if isinstance(adv,Adv):
        return LexSem(lemma,"Adv",[":op1"],lambda op1:AdvP(copy.deepcopy(adv),accPron(op1)))
    if isinstance(adv,str):
        return LexSem(lemma,"Adv",[":op1"],lambda op1:Adv(adv) if op1==None else AdvP(Adv(adv),accPron(op1)))
    print("### strange adverb:"+str(adv))
    return adverbs[lemma]
Пример #10
0
def frequencyRole(semR, env, opts):
    traceSyntR("frequencyRole", semR)
    concept = semR.get_concept()
    instance = semR.get_instance()
    if concept == None and is_number(instance):
        if instance == 1:
            env.push(Adv("once"))
        elif instance == 2:
            env.push(D("twice"))
        else:
            env.push(NP(NO(instance), N("time")))
    else:
        env.push(makeSyntR(semR))
Пример #11
0
def pathRole(semR, env, opts):
    traceSyntR("pathRole", semR)
    concept = semR.get_concept()
    if concept == "past" and ":op1" in semR.roles:
        env.push(AdvP(Adv("past"), makeSyntR(semR.roles[":op1"])))
    else:
        syntR = makeSyntR(semR)
        if isinstance(syntR, Pro):
            syntR.lemma = "me"
        else:
            if isinstance(syntR, (Adv, P, PP)):
                env.push(syntR)
            else:
                env.push(PP(P("via"), syntR))
Пример #12
0
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))
Пример #13
0
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)])
Пример #14
0
 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
Пример #15
0
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
Пример #16
0

jsrAbnormal = {
    "night": {
        "a": {
            "en":
            lambda t, _: temp_trend("en", "rise", t, PP(P("by"), N("morning"))
                                    ),
            "fr":
            lambda t, _: temp_trend("fr", "hausse", t, PP(
                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")))
        },
Пример #17
0
def clearSavedJsrIO():
    savedJsrIO=[]

def getSavedJsrIO():
    return savedJsrIO

def realize(jsrExpr,lang,addS=True):
    if addS and not isinstance(jsrExpr,S):
        jsrExpr=S(jsrExpr)
    realization=jsRealB(jsrExpr.set_lang(lang).pp())
    if savedJsrIO!=None:
        savedJsrIO.append((jsrExpr.show(),realization))
    return realization

dayPeriods=[(0,5,{"en":lambda:NP(N("night")),"fr":lambda:NP(N("nuit"))}),
            (5,9,{"en":lambda:NP(Adv("early"),N("morning")),"fr":lambda:NP(N("début"),PP(P("de"),N("matinée")))}),
            (9,12,{"en":lambda:NP(N("morning")),"fr":lambda:NP(N("matin"))}),
            (12,18,{"en":lambda:NP(N("afternoon")),"fr":lambda:NP(N("après-midi"))}),
            (18,24,{"en":lambda:NP(N("tonight")),"fr":lambda:NP(N("soir"))}),
            ]

def jsrDayPeriod(hour,lang):
    isTomorrow=hour>23
    hour=hour%24
    for (s,e,jsrExp) in dayPeriods:
        if hour in range(s,e):
            exp=jsrExp[lang]()
            if isTomorrow:
                return exp.add(N("tomorrow" if lang=="en" else "demain"),0)
            elif s!=18:
                return exp.add(D("this" if lang=="en" else "ce"),0)
Пример #18
0
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):
Пример #19
0
conjunctions["sum-of"]=op16("and")
conjunctions["ratio-of"]=op12("ratio-of",NP(N("ratio"),P("of")),"to")
conjunctions["difference-of"]=op16("minus")
conjunctions["quotient-of"]=op16("divided by")
conjunctions["power-of"]=op16("to the power of")
conjunctions["root-of"]= LexSem("root-of","P",[":op1",":op2"],
                                lambda op1,op2:NP(NO(op2[0].lemma).dOpt({"ord":True}),N("root"),PP(P("of"),op1)))
conjunctions["logarithm-of"]= LexSem("log-of","P",[":op1",":op2"],
                                     lambda op1,op2:NP(N("logarithm"),PP(P("of"),op1,N("base").a(":"),op2)))

def isConjunction(lemma):return lemma in conjunctions
def makeCP(lemma):
    return  conjunctions[lemma]

### Adverbs
adverbs["et-cetera"]=AdvP(Adv("etc"))
adverbs["at-least"]=AdvP(P("at"),Adv("least"))
adverbs["next-to"]=AdvP(Adv("next"),P("to"))
adverbs["kind-of"]=AdvP(Q("kind of"))
adverbs["away"]=AdvP(Adv("away"),P("from"))
delCat(adverbs,"between")
delCat(adverbs,"near")
delCat(adverbs,"this")
delCat(adverbs,"that")
delCat(adverbs,"after") # keep only prep
delCat(adverbs,"this")

def isAdverb(lemma):return lemma in adverbs
def makeAdv(lemma):
    adv=adverbs[lemma]
    if isinstance(adv,AdvP):
Пример #20
0
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

### Pubpro sec 2.3.4
## vents : start end direction modif? speed value exception?
# e | nil | n | ne | nw | w | ely | nly | nely | nwly | wly | sly| sely | swly | sly | sely | sw | vrbl
jsrWindDirection = {
    "e": {
        "en": Adv("east"),
        "fr": NP(D("le"), N("est")),
        "deg": 90
    },
    "n": {
        "en": Adv("north"),
        "fr": NP(D("le"), N("nord")),
        "deg": 0
    },
    "ne": {
        "en": Adv("northeast"),
        "fr": NP(D("le"), N("nord-est")),
        "deg": 45
    },
    "nw": {
        "en": Adv("northwest"),
        "fr": NP(D("le"), N("nord-ouest")),
        "deg": 315
    },
    "w": {
        "en": Adv("west"),
        "fr": NP(D("le"), N("ouest")),
        "deg": 290
Пример #21
0
def haveDegree91(concept,roles,env,opts):
    traceSyntR("haveDegree91",concept)
    subject=None
    attribute=None
    comp=""
    quant=None
    if ":ARG1" in roles:
        arg1=roles[":ARG1"]
#         print("haveDegree1:",arg1.instanceIsRef())
        if not arg1.instanceIsRef(): # do not follow link for subject
            subject=makeSyntR(arg1)
    if ":ARG2" in roles:
        concept=roles[":ARG2"].concept
        attribute=makeSyntR(roles[":ARG2"])
        # HACK: remove spurious pronouns created by starrole
        if isinstance(attribute, AP) and len(attribute.elements)>1 and isinstance(attribute.elements[1],Pro):
            del attribute.elements[1]
            if len(attribute.elements)==1:
                attribute=attribute.elements[0]
    else:
        errorSyntR("have-degree-91 without :ARG2:%s"%concept)
        return Q("degree-91")
    if ":mod" in roles:
        if isinstance(attribute,Terminal):
            attribute=AP(attribute)
        attribute.add(makeSyntR(roles[":mod"]))        
    if ":ARG3" in roles:
        rolesARG3=roles[":ARG3"]
        deg=rolesARG3.get_concept()
        moreRoles=rolesARG3.get_roles()
        if moreRoles!=None and len(moreRoles)>0:
            if ":quant" in moreRoles:
                quant=makeSyntR(moreRoles[":quant"])
            else:
                attribute.add(makeSyntR(moreRoles[0][1]))
        if deg=="more":
            attribute=attribute.f("co")
            if quant!=None:
                attribute=NP(quant,attribute)
                quant=None
            comp="co"
        elif deg=="most":
            if isinstance(attribute,A):
                attribute=AP(D("the"),attribute.f("su"))
            else:
                attribute=AP(attribute,D("the"),Adv("most"))
            comp="su"
        elif deg in ["too","so","less"]:
            attribute=AdvP(Adv(deg),attribute)
            if deg=="less":
                comp="co"
            elif quant!=None:
                attribute=AP(attribute,quant)
                quant=None
        elif deg=="equal":
            attribute=AdvP(Adv("as"),attribute,Adv("as"))
        elif deg=="times":
            if quant!=None:
                quant=NP(quant,N("time"))
                attribute=attribute.f("co")
            comp="co"
        else:
            attribute=AdvP(attribute,Adv(deg))
    if ":ARG4" in roles:
        syntR4=makeSyntR(roles[":ARG4"])
        if comp=="co":
            attribute=PP(attribute,P("than"),syntR4)
            if quant!=None:
                attribute.add(quant,0)
        elif comp=="su":
            attribute=AP(attribute,Adv("in"),syntR4)
        else:
            attribute.add(syntR4)
    if ":ARG5" in roles:
        attribute.add(makeSyntR(roles[":ARG5"]))
    if ":ARG6" in roles:
        attribute=NP(attribute,makeSyntR(roles[":ARG6"]))
#     print("have-degree-91:subject:",subject)
    while ":li" in roles:
        semR=roles[":li"]
        del roles[":li"]
        ## analogous to roleProcessing.lirole
        semR_i=unquote(semR.get_instance())
        if semR_i=="-1":
            attribute.add(Adv("lastly"),0)
        elif semR_i=="1":
            attribute.add(Adv("first"),0)
        elif is_number(semR_i):
            attribute.add(Q("("+str(semR_i)+")"),0)
        elif semR_i[0]=='"':
            attribute.add(Q("("+semR_i+")"),0)
    restRoles=addRoles(concept, roles, [":ARG1",":ARG2",":ARG3",":ARG4",":ARG5",":ARG6",":li",":mod",":polarity"], 
                       LexSem("degree","SP",[],lambda:SP()),env, opts)        
    if len(restRoles.elements)>0:
        attribute=ensurePhrase(attribute).add(restRoles)
    if subject!=None:
        attribute=predicate(subject,attribute)
        if hasNegPolarity(roles):
            return attribute.typ({"neg":True})
    else:
        if hasNegPolarity(roles):
            return AdvP(Adv("not"),attribute)
    return attribute
Пример #22
0
def quantRole(semR, env, opts):
    def processSimpleQuant(concept):
        simpleQuants = {  # concept: string to add to the start, boolean to indicate if plural
            "most": ["most of", True],
            "more": ["more", True],
            "numerous": ["numerous", True],
            "many": ["many", True],
            "multiple": ["multiple", True],
            "few": ["few", True],
            "some": ["some", False],
            "such": ["a sack of", False],
            "last": ["last", False],
            "one": ["one", False],
            "entire": ["entire", False],
            "lot": ["a lot", False],
            "sack": ["a sack of", False]
        }
        if concept in simpleQuants:
            if concept == "lot":
                env.push(Q(simpleQuants[concept][0]))
            else:
                env.unshift(Q(simpleQuants[concept][0]))
            if simpleQuants[concept][1]: opts.add("n", "p")
            return True
        return False

    #  fuzzy operators from https://www.isi.edu/~ulf/amr/lib/popup/quantities.html#non-exact-quantities
    #  role :op1
    #  about, above, almost, approximately, around, at-least, at-most, below, close-to, couple, few, less-than,
    #  lot, many, more-than, multiple, nearly, no-more-than, over, roughly, several, some, under, up-to
    #  number is dealt separately
    def fuzzyQuant1(concept):
        fuzzyQuants = [
            'about', 'above', 'almost', 'approximately', 'around', 'at-least',
            'at-most', 'below', 'close-to', 'couple', 'few', 'less-than',
            'lot', 'many', 'more-than', 'nearly', 'no-more-than', 'over',
            'roughly', 'several', 'some', 'under', 'up-to'
        ]
        if concept == "multiple":
            env.unshift(Q("multiple"))
            env.push(Q("of"))
            if ":op1" in semR.roles:
                env.push(makeSyntR(semR.roles[":op1"]))
            return True
        if concept in fuzzyQuants and ":op1" in semR.roles:
            env.put(
                ":D",
                AP(Q(generateConceptWord(concept)),
                   makeSyntR(semR.roles[":op1"])))
            opts.add("n", "p")
            return True
        return False

    def fuzzyQuant2(concept):
        roles = semR.get_roles()
        if ":op1" in roles and ":op2" in roles:
            env.put(
                ":D",
                PP(P("between"), makeSyntR(roles[":op1"]), C("and"),
                   makeSyntR(roles[":op2"])))
            return True
        return False

    traceSyntR("quantRole", semR)
    concept = semR.get_concept()
    roles = semR.roles
    if len(roles) == 0 and processSimpleQuant(concept): return
    if fuzzyQuant1(concept): return
    if fuzzyQuant2(concept): return
    if isinstance(concept, str) and re.match(r'.+-quantity$', concept):
        env.unshift(
            PP(specialConcept.quantity(concept, roles, Env(), Options()),
               P("of")))
        return

    if concept == "amr-unknown":
        env.unshift(AdvP(Adv("how"), Adv("much")))
        opts.add("a", "?")
    else:
        syntR = makeSyntR(semR, False)
        if isinstance(syntR, NO):
            env.put(":D", syntR)
        else:
            env.unshift(PP(syntR, P("of")))