Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compilation hangs with param variants, succeeds with record variants #132

Open
inariksit opened this issue Aug 25, 2021 · 0 comments
Open
Labels
bug Something isn't working

Comments

@inariksit
Copy link
Member

TL;DR

  • I have a piece of code where, if I use variants inside a param:

      PNegInlineVariants : Pol = lin Pol {s = [] ; p = ResEng.CNeg (True|False)} ;    -- Doesn't compile

    it doesn't compile. When I change it into variants on the record level, it works just fine.

      PNegTopVariants  : Pol = lin Pol ( {s = [] ; p = R.CNeg True }                 -- Compiles
                                       | {s = [] ; p = R.CNeg False}) ; 
  • Tested with GF 3.11 and GF 3.10 (from December 2018), both have the bug.

  • Full example code is in my repo https://github.com/inariksit/gf-variants-bug

Now follows the long explanation.

Grammars

Abstract: TestVariants.gf

abstract TestVariants = {
  cat
    S ; Subj ; Pred ;
  fun
    PredVP : Subj -> Pred -> S ;
    cat_Subj : Subj ;
    doesnt_sit_Pred : Pred ;
}

Concrete with bug: TestVariantsBugEng.gf

The category Pred is has lincat ExtendEng.VPS, like this.

lincat
  Pred = ExtendEng.VPS ;

In addition, we have an oper that allows both contracted and uncontracted negation.

oper
  PNegInlineVariants : Pol = lin Pol {s = [] ; p = ResEng.CNeg (True|False)} ;

The issue comes in the linearisation of doesnt_sit_Pred, which is defined as follows.

lin
  doesnt_sit_Pred =
    let temp : Temp = mkTemp pastTense simultaneousAnt ;
        vp   : VP   = mkVP sit_V ;
     in ExtendEng.MkVPS temp PNegInlineVariants vp ;

However, this version of the same grammar compiles just fine. It's still using variants, but now they are not on the level of params, but rather the whole record.

oper
  PNegTopVariants  : Pol = lin Pol ( {s = [] ; p = R.CNeg True }
                                   | {s = [] ; p = R.CNeg False}
                                   ) ;
lin
  doesnt_sit_Pred =
    let temp : Temp = mkTemp pastTense simultaneousAnt ;
        vp   : VP   = mkVP sit_V ;
     in ExtendEng.MkVPS temp PNegTopVariants vp ;

The bug

When I try to compile the code that uses PNegInlineVariants, it gets stuck at doesnt_sit_Pred.

$ gf -v TestVariantsBugEng.gf
…
- parsing TestVariantsBugEng.gf
  renaming
  type checking
  optimizing  PNegInlineVariants
 doesnt_sit_Pred
 cat_Subj
 Subj
 S
 PredVP
 Pred
 PNegTopVariants

  generating PMCFG
+ Pred 1
+ PredVP 10 (10,10)
+ S 1
+ Subj 10
+ cat_Subj 1 (1,1)
+ doesnt_sit_Pred 1

It is stuck there in what seems to be an infinite loop. I added debug output in getFIds, and this is what it spits out:

+ doesnt_sit_Pred 1
-------
getFIds
Pred
1 Pred
CRec [LIdent (Id {rawId2utf8 = "s"}),LIdent (Id {rawId2utf8 = "lock_VPS"})]
-------
getFIds.variants: found a record
getFIds.variants: found a table Order
getFIds.variants: found a table Agr
getFIds.variants: found a record
getFIds.variants: recursion ended on string 0
getFIds.variants: recursion ended on string 1
getFIds.variants: found a record
…
getFIds.variants: recursion ended on string 58
getFIds.variants: recursion ended on string 59
getFIds.variants: found a record

-------
getFIds
Pred
1 Pred
CRec [LIdent (Id {rawId2utf8 = "s"}),LIdent (Id {rawId2utf8 = "lock_VPS"})]
-------
getFIds.variants: found a record
getFIds.variants: found a table Order
getFIds.variants: found a table Agr
getFIds.variants: found a record
getFIds.variants: recursion ended on string 0
getFIds.variants: recursion ended on string 1


… more of the same until I press Ctrl+C

So there's something that calls getFIds over and over again, the subfunction getFIds.variants ends every time. This is the stack trace from when I pressed Ctrl+C: getFIds is called most immediately from GeneratePMCFG.addPMCFG.addRule, but that doesn't mean the looping happens there–there are many other functions where I didn't put debug output.

*** Exception (reporting due to +RTS -xc): (base:GHC.Exception.Type.SomeException), stack trace:
  GF.Compile.GeneratePMCFG.getFIds.variants,
  called from GF.Compile.GeneratePMCFG.getFIds,
  called from GF.Compile.GeneratePMCFG.addPMCFG.addRule.(...),
  called from GF.Compile.GeneratePMCFG.addPMCFG.addRule,
  called from GF.Data.BacktrackM.return.\,
  called from GF.Data.BacktrackM.return,
  called from GF.Data.BacktrackM.>>=.\.\,
  called from GF.Data.BacktrackM.member.\.\,
  called from GF.Data.BacktrackM.member.\,
  called from GF.Data.BacktrackM.member,
  called from GF.Data.BacktrackM.>>=.\,
  called from GF.Data.BacktrackM.>>=,
  called from GF.Compile.GeneratePMCFG.goV,
  called from GF.Compile.GeneratePMCFG.goB,
  called from GF.Data.BacktrackM.foldBM,
  called from GF.Compile.GeneratePMCFG.addPMCFG.pmcfgEnv1,
  called from GF.Compile.GeneratePMCFG.addPMCFG,
  called from GF.Compile.GeneratePMCFG.mapAccumWithKeyM.mapAccumM,
  called from GF.Compile.GeneratePMCFG.mapAccumWithKeyM,
  called from GF.Compile.GeneratePMCFG.generatePMCFG,

Other observations

I tried to make a more minimal version of the grammar, that doesn't use the RGL, but has the same inline variants.

The full grammar is at TestVariantsNoRGLNoBug.gf. I defined the parameters as follows:

  param
    Bool = True | False ;
    CPolarity = CPos | CNeg Bool ;

  oper
    Pol : Type = {s : Str ; p : CPolarity} ;
    PNegInlineVariants : Pol = {s = [] ; p = CNeg (True|False)} ;
    PNegTopVariants    : Pol = {s = [] ; p = CNeg True } |
                               {s = [] ; p = CNeg False} ;

But when I use PNegInlineVariants in the linearisation of doesnt_sit_Pred, it compiles happily.

@inariksit inariksit added the bug Something isn't working label Aug 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant