What do you want to achieve with having different tenses as variants? With tenses as variants, I'm thinking of a situation where tense doesn't make a difference in your application grammar, and you want to parse sentences like "I buy food" and "I bought food" into the same tree.
I'm going to show how to do it, but first, let's fix the syntax error.
Fixing the syntax error
I don't understand what is your aim with variants {"write", "wrote" ; "buy", "bought" ; "read", "read}. First of all, this is a syntax error in GF: the terms between ; or | must be valid GF expressions, but "write", "wrote" is two strings separated by a comma, which is not a valid GF expression.
If you really create a variant that includes any verb in any tense, replace the commas with semicolons. Like this:
all_verbs : Str = variants { "write" ; "wrote" ; "buy" ; "bought" ; "read"} ;
Testing in GF shell:
> cc -all all_verbs
write / wrote / buy / bought / read
If you want just the tenses, then you can write this:
write : Str = variants {"write" ; "wrote"} ;
buy : Str = variants {"buy" ; "bought"} ;
Looks like this in the GF shell:
> cc -all write
write / wrote
Tenses as variants in an application grammar
I've written a small application grammar, where I demonstrate the best way to do this using the RGL. The link is here: https://gist.github.com/inariksit/b444a01b0a23468b7a558e39c6ce06fd The crucial thing is, as you see in the code, that the verbs are completely normal, and we add the variants only at the sentence level. That is much safer than trying to introduce variants in the verbs' inflection tables.
This grammar behaves as follows:
1. linearize only outputs the first option.
TenseVariants> l Pred Cat Sleep
the cat sleeps
2. parse accepts both.
TenseVariants> p "the cat sleeps"
Pred Cat Sleep
TenseVariants> p "the cat slept"
Pred Cat Sleep
If you want to control when to output "sleeps" and when "slept", then you can't do it with variants: you need to actually have two different abstract syntax trees that correspond to the two outputs.
However, if you only need to output one of the forms, but want to parse both, then variants is a right choice.
Nondeterminism in GF
I'm curious what was the reason you wanted to put all verbs under the same variant? It's already possible to generate all combinations with GF, using the gt ("generate trees") command:
TenseVariants> gt Pred Cat ? | l
the cat reads
the cat sleeps
the cat writes
The question mark is in the place of the verb, and what gt does is that it replaces the question mark with all suitable expressions in the grammar.[1]
Combine this with the flag -all for linearize, and you get this:
TenseVariants> gt Pred Cat ? | l -all
the cat reads
the cat read
the cat sleeps
the cat slept
the cat writes
the cat wrote
If I misunderstood your goal with the variants, or something else is unclear, let me know and I'll be glad to clarify!
[1] Try running this command in the resource grammar and see what happens!
$ gf alltenses/LangEng.gfo
Lang> gt PredVP (UsePron ?) (UseComp (CompAP (PositA ?)))
You'll get a long list of stuff. If you only want to generate one, use the command gr ("generate random").
Lang> gr PredVP (UsePron ?) (UseComp (CompAP (PositA ?))) | l -treebank
Lang: PredVP (UsePron i_Pron) (UseComp (CompAP (PositA bad_A)))
LangEng: I am bad