Let's say I want to write a code that greets people, but for some reason, I don't want to greet a person called John, and I want GF to generate this kind of sentence.
Abstract Version
I knew that this kind of result is achievable from the abstract file such as follow: GreetingFromAbstract.gf
abstract GreetingFromAbstract = {
flags startcat = Sentence;
cat
Relation;
Sentence;
Verb Relation;
Noun Relation;
fun
MySentence : (rel : Relation) -> Verb rel -> Noun rel -> Sentence;
Say : Verb RelA;
Mike : Noun RelA;
John : Noun RelB;
RelA, RelB : Relation;
}
And the concrete file would be like this:
GreetingFromAbstractEng.gf
concrete GreetingFromAbstractEng of GreetingFromAbstract = open SyntaxEng, ParadigmsEng, IrregEng, Prelude in {
lincat
Sentence = Phr;
Verb = V3;
Noun = N;
Relation = {s : Str};
lin
MySentence _ action person = sayHi (action) (person);
Say = mkV3(say_V) (noPrep) (to_Prep);
Mike = mkN("Mike");
John = mkN("John");
RelA, RelB = {s = ""};
oper
-- Generate the final sentence
sayHi : V3 -> N -> Phr =
\v, n -> mkPhr(mkUtt(mkImp(mkVP
(v)
(mkNP (mkN "hi"))
(mkNP (n)))));
}
Puzzle
But let's say for some reason I don't want to do that from the abstract file but from the concrete. I want the person that is writing the names to decide which person to say hi to, and which is not.
Concrete Version
According to my problem, I wrote this code: GreetingFromConcrete.gf
abstract GreetingFromConcrete = {
flags startcat = Sentence;
cat
Sentence; Verb; Noun;
fun
MySentence : Verb -> Noun -> Sentence;
Say : Verb;
Mike : Noun;
John : Noun;
}
And the concrete: GreetingFromConcreteEng.gf
concrete GreetingFromConcreteEng of GreetingFromConcrete = open SyntaxEng, ParadigmsEng, IrregEng, Prelude in {
lincat
Sentence = Phr;
Verb = {v : V3 ; rel : Relation};
Noun = {n : N ; rel : Relation};
lin
-- MySentence first judge if these two given variables are a good match
MySentence action person = case <action.rel, person.rel> of {
<RelA, RelA> => sayHi (action.v) (person.n);
<RelB, RelB> => sayHi (action.v) (person.n);
<_, _> => sayHi (action.v) (mkN(nonExist))
};
Say = {v = mkV3(say_V) (noPrep) (to_Prep); rel = RelA};
Mike = {n = mkN("Mike") ; rel = RelA};
John = {n = mkN("John") ; rel = RelB};
param
Relation = RelA | RelB;
oper
-- Generate the final sentence
sayHi : V3 -> N -> Phr =
\v, n -> mkPhr(mkUtt(mkImp(mkVP
(v)
(mkNP (mkN "hi"))
(mkNP (n)))));
}
Problem
My solution is obviously not the best to offer since it would result in generating 50% empty sentences when using the command gr | l
, which would get worse the larger the parameter Relation
is.
Questions
1- Is there any way to force abstract to give only matched parameters from the concrete file?
2- Or Is there any possible way to ask abstract to give another parameter when not matched from concrete instead of just generating the empty line using nonExist
?