// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*-
//
// This file is part of Genie
//
// Copyright 2020 The Board of Trustees of the Leland Stanford Junior University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Giovanni Campagna <gcampagn@cs.stanford.edu>

// Templates that describe results from a query

import assert from 'assert';
import { Ast, } from 'thingtalk';
import * as C from '../../ast_manip';
import * as D from '../../dialogue_acts';
import * as S from '../../state_manip';
import { SlotBag } from '../../slot_bag';
import ThingpediaLoader from '../../load-thingpedia';
import type * as $Genie from "genie-toolkit";
export default async function($runtime : typeof $Genie.SentenceGeneratorRuntime, $ttUtils : typeof $Genie.ThingTalkUtils, $options : $Genie.SentenceGeneratorTypes.GrammarOptions, $locale : $Genie.I18n.LanguagePack, $grammar : $Genie.SentenceGenerator<any, any>, $loader : ThingpediaLoader) : Promise<void> {
   $grammar.declareSymbol("result_name_pair");
   $grammar.addRule("result_name_pair", [new $runtime.NonTerminal("ctx_with_result", undefined), new $runtime.NonTerminal("constant_name", ["value" as ("value" extends keyof ReturnType<typeof C.entityOrNumberValueKeyFn> ? string : void), 0, "id0" as ("id0" extends keyof ReturnType<typeof S.contextKeyFn> ? string : void)]), ",", new $runtime.NonTerminal("constant_name", ["value" as ("value" extends keyof ReturnType<typeof C.entityOrNumberValueKeyFn> ? string : void), 0, "id1" as ("id1" extends keyof ReturnType<typeof S.contextKeyFn> ? string : void)])], ((ctx : S.ContextInfo, n1 : Ast.EntityValue|Ast.NumberValue, $0 : undefined, n2 : Ast.EntityValue|Ast.NumberValue) : (D.NameList)|null => {
        const results = ctx.results;
        assert(results && results.length >= 2);
        assert(ctx.resultInfo!.idType !== null);

        const r1 = results[0];
        const r2 = results[1];
        if (!r1.value.id.equals(n1)) // can happen if the types are different but the value is the same
            return null;
        if (!r2.value.id.equals(n2))
            return null;
        return { ctx, results: results.slice(0, 2) };
    }), D.nameListKeyFn, {  });
   $grammar.declareSymbol("result_name_list");
   $grammar.addRule("result_name_list", [new $runtime.NonTerminal("ctx_with_result", undefined), new $runtime.NonTerminal("constant_name", ["value" as ("value" extends keyof ReturnType<typeof C.entityOrNumberValueKeyFn> ? string : void), 0, "id0" as ("id0" extends keyof ReturnType<typeof S.contextKeyFn> ? string : void)]), new $runtime.Choice(["and", "or"]), new $runtime.NonTerminal("constant_name", ["value" as ("value" extends keyof ReturnType<typeof C.entityOrNumberValueKeyFn> ? string : void), 0, "id1" as ("id1" extends keyof ReturnType<typeof S.contextKeyFn> ? string : void)])], ((ctx : S.ContextInfo, n1 : Ast.EntityValue|Ast.NumberValue, $0 : undefined, n2 : Ast.EntityValue|Ast.NumberValue) : (D.NameList)|null => {
        const results = ctx.results;
        assert(results && results.length >= 2);
        assert(ctx.resultInfo!.idType !== null);

        const r1 = results[0];
        const r2 = results[1];
        if (!r1.value.id.equals(n1))
            return null;
        if (!r2.value.id.equals(n2))
            return null;
        return { ctx, results: results.slice(0, 2) };
    }), D.nameListKeyFn, { priority: (2) });
   $grammar.addRule("result_name_list", [new $runtime.NonTerminal("result_name_pair", undefined), new $runtime.Choice(["and", "or"]), new $runtime.NonTerminal("constant_name", ["value" as ("value" extends keyof ReturnType<typeof C.entityOrNumberValueKeyFn> ? string : void), 0, "id2" as ("id2" extends keyof ReturnType<typeof D.nameListKeyFn> ? string : void)])], ((pair : D.NameList, $0 : undefined, n3 : Ast.EntityValue|Ast.NumberValue) : (D.NameList)|null => {
        const ctx = pair.ctx;
        const results = ctx.results;
        assert(results && results.length >= 3);
        assert(ctx.resultInfo!.idType !== null);
        const r3 = results[2];
        if (!r3.value.id.equals(n3))
            return null;
        return { ctx, results: results.slice(0, 3) };
    }), D.nameListKeyFn, { priority: (3) });
   $grammar.declareSymbol("direct_result_info_phrase");
   $grammar.addRule("direct_result_info_phrase", [new $runtime.NonTerminal("one_param_direct_result_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { identity: (true) });
   $grammar.addRule("direct_result_info_phrase", [new $runtime.NonTerminal("two_param_direct_result_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { identity: (true) });
   $grammar.addRule("direct_result_info_phrase", [new $runtime.NonTerminal("three_param_direct_result_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { identity: (true) });
   $grammar.declareSymbol("one_param_direct_result_info_phrase");
   $grammar.addRule("one_param_direct_result_info_phrase", [new $runtime.NonTerminal("ctx_with_result", undefined), "the", new $runtime.NonTerminal("out_param_Any", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.paramKeyFn> ? string : void), 0, "currentFunction" as ("currentFunction" extends keyof ReturnType<typeof S.contextKeyFn> ? string : void)]), "is", new $runtime.NonTerminal("constant_Any", ["type" as ("type" extends keyof ReturnType<typeof C.valueKeyFn> ? string : void), 2, "type" as ("type" extends keyof ReturnType<typeof C.paramKeyFn> ? string : void)])], ((ctx : S.ContextInfo, $0 : undefined, param : C.ParamSlot, $1 : undefined, v : Ast.Value) : (D.ResultPhrase)|null => {
        assert(param.type.equals(v.getType()));
        const bag = new SlotBag(param.schema);
        bag.set(param.name, v);
        return D.makeResultPhrase(ctx, bag);
    }), D.resultPhraseKeyFn, {  });
   $grammar.addRule("one_param_direct_result_info_phrase", [new $runtime.NonTerminal("ctx_with_result", undefined), "the distance is", new $runtime.NonTerminal("constant_Measure_m", undefined)], ((ctx : S.ContextInfo, $0 : undefined, v : Ast.Value) : (D.ResultPhrase)|null => {
        const bag = new SlotBag(null);
        bag.set('distance', v);
        return D.makeResultPhrase(ctx, bag);
    }), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("two_param_direct_result_info_phrase");
   $grammar.addRule("two_param_direct_result_info_phrase", [new $runtime.NonTerminal("one_param_direct_result_info_phrase", undefined), "and", new $runtime.NonTerminal("one_param_direct_result_info_phrase", undefined)], ((b1 : D.ResultPhrase, $0 : undefined, b2 : D.ResultPhrase) : (D.ResultPhrase)|null => D.mergeResultPhrase(b1, b2)), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("three_param_direct_result_info_phrase");
   $grammar.addRule("three_param_direct_result_info_phrase", [new $runtime.NonTerminal("one_param_direct_result_info_phrase", undefined), ",", new $runtime.NonTerminal("two_param_direct_result_info_phrase", undefined)], ((b1 : D.ResultPhrase, $0 : undefined, b2 : D.ResultPhrase) : (D.ResultPhrase)|null => D.mergeResultPhrase(b1, b2)), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("result_info_phrase");
   $grammar.addRule("result_info_phrase", [new $runtime.NonTerminal("one_with_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { weight: (0.33*2), priority: (1), identity: (true) });
   $grammar.addRule("result_info_phrase", [new $runtime.NonTerminal("one_which_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { weight: (0.33*2), priority: (1), identity: (true) });
   $grammar.addRule("result_info_phrase", [new $runtime.NonTerminal("one_clean_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { weight: (0.33*2), priority: (1), identity: (true) });
   $grammar.addRule("result_info_phrase", [new $runtime.NonTerminal("two_with_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { weight: (0.33), priority: (2), identity: (true) });
   $grammar.addRule("result_info_phrase", [new $runtime.NonTerminal("two_which_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { weight: (0.33), priority: (2), identity: (true) });
   $grammar.addRule("result_info_phrase", [new $runtime.NonTerminal("two_clean_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { weight: (0.33), priority: (2), identity: (true) });
   $grammar.addRule("result_info_phrase", [new $runtime.NonTerminal("three_with_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { weight: (0.33*0.5), priority: (-1), identity: (true) });
   $grammar.addRule("result_info_phrase", [new $runtime.NonTerminal("three_which_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { weight: (0.33*0.5), priority: (-1), identity: (true) });
   $grammar.addRule("result_info_phrase", [new $runtime.NonTerminal("three_clean_info_phrase", undefined)], (($0 : D.ResultPhrase) : (D.ResultPhrase)|null => { return $0; }), D.resultPhraseKeyFn, { weight: (0.33*0.5), priority: (-1), identity: (true) });
   $grammar.declareSymbol("base_result_phrase");
   $grammar.addRule("base_result_phrase", [new $runtime.NonTerminal("ctx_with_result", undefined), new $runtime.NonTerminal("base_table", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.expressionKeyFn> ? string : void), 0, "currentFunction" as ("currentFunction" extends keyof ReturnType<typeof S.contextKeyFn> ? string : void)])], ((ctx : S.ContextInfo, table : Ast.InvocationExpression) : (D.ResultPhrase)|null => {
        assert(table.schema instanceof Ast.FunctionDef);
        return D.makeResultPhrase(ctx, new SlotBag(table.schema));
    }), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("one_with_info_phrase");
   $grammar.addRule("one_with_info_phrase", [new $runtime.NonTerminal("base_result_phrase", undefined), new $runtime.Choice(["with", "having"]), new $runtime.NonTerminal("npp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("one_which_info_phrase");
   $grammar.addRule("one_which_info_phrase", [new $runtime.NonTerminal("base_result_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npi_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("one_which_info_phrase", [new $runtime.NonTerminal("base_result_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.NonTerminal("avp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("one_which_info_phrase", [new $runtime.NonTerminal("base_result_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("apv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, { priority: (-0.1) });
   $grammar.addRule("one_which_info_phrase", [new $runtime.NonTerminal("base_result_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("one_clean_info_phrase");
   $grammar.addRule("one_clean_info_phrase", [new $runtime.NonTerminal("apv_filter", undefined), new $runtime.NonTerminal("base_result_phrase", ["functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void)])], ((filter : C.FilterSlot, table : D.ResultPhrase) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("one_clean_info_phrase", [new $runtime.NonTerminal("base_result_phrase", undefined), new $runtime.NonTerminal("pvp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("one_clean_info_phrase", [new $runtime.NonTerminal("base_result_phrase", undefined), new $runtime.NonTerminal("preposition_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("two_with_info_phrase");
   $grammar.addRule("two_with_info_phrase", [new $runtime.NonTerminal("one_with_info_phrase", undefined), "and", new $runtime.NonTerminal("npp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_with_info_phrase", [new $runtime.NonTerminal("one_which_info_phrase", undefined), new $runtime.Choice(["and having", "and with", ", with"]), new $runtime.NonTerminal("npp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_with_info_phrase", [new $runtime.NonTerminal("one_clean_info_phrase", undefined), new $runtime.Choice(["with", "having"]), new $runtime.NonTerminal("npp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_with_info_phrase", [new $runtime.NonTerminal("apv_filter", undefined), new $runtime.NonTerminal("base_result_phrase", ["functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void)])], ((filter : C.FilterSlot, table : D.ResultPhrase) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("two_which_info_phrase");
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_with_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npi_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_with_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.NonTerminal("avp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_with_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("apv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, { priority: (-0.1) });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_with_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_which_info_phrase", undefined), "and", new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npi_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_which_info_phrase", undefined), "and", new $runtime.NonTerminal("avp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_which_info_phrase", undefined), "and", new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("apv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, { priority: (-0.1) });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_which_info_phrase", undefined), "and", new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_clean_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npi_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_clean_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.NonTerminal("avp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_clean_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("apv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, { priority: (-0.1) });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("one_clean_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_which_info_phrase", [new $runtime.NonTerminal("apv_filter", undefined), new $runtime.NonTerminal("one_which_info_phrase", ["functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void)])], ((filter : C.FilterSlot, table : D.ResultPhrase) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("two_clean_info_phrase");
   $grammar.addRule("two_clean_info_phrase", [new $runtime.NonTerminal("apv_filter", undefined), new $runtime.NonTerminal("one_clean_info_phrase", ["functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void)])], ((filter : C.FilterSlot, table : D.ResultPhrase) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_clean_info_phrase", [new $runtime.NonTerminal("one_clean_info_phrase", undefined), new $runtime.NonTerminal("pvp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("two_clean_info_phrase", [new $runtime.NonTerminal("one_clean_info_phrase", undefined), new $runtime.NonTerminal("preposition_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("three_with_info_phrase");
   $grammar.addRule("three_with_info_phrase", [new $runtime.NonTerminal("two_with_info_phrase", undefined), "and", new $runtime.NonTerminal("npp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_with_info_phrase", [new $runtime.NonTerminal("two_which_info_phrase", undefined), new $runtime.Choice(["and having", "and with", ", with"]), new $runtime.NonTerminal("npp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_with_info_phrase", [new $runtime.NonTerminal("two_clean_info_phrase", undefined), new $runtime.Choice(["with", "having"]), new $runtime.NonTerminal("npp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_with_info_phrase", [new $runtime.NonTerminal("apv_filter", undefined), new $runtime.NonTerminal("two_with_info_phrase", ["functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void)])], ((filter : C.FilterSlot, table : D.ResultPhrase) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("three_which_info_phrase");
   $grammar.addRule("three_which_info_phrase", [new $runtime.NonTerminal("two_with_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npi_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_which_info_phrase", [new $runtime.NonTerminal("two_with_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.NonTerminal("avp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_which_info_phrase", [new $runtime.NonTerminal("two_with_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("apv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_which_info_phrase", [new $runtime.NonTerminal("two_which_info_phrase", undefined), "and", new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npi_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_which_info_phrase", [new $runtime.NonTerminal("two_which_info_phrase", undefined), "and", new $runtime.NonTerminal("avp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_which_info_phrase", [new $runtime.NonTerminal("two_which_info_phrase", undefined), "and", new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("apv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_which_info_phrase", [new $runtime.NonTerminal("two_clean_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("npi_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_which_info_phrase", [new $runtime.NonTerminal("two_clean_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.NonTerminal("avp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_which_info_phrase", [new $runtime.NonTerminal("two_clean_info_phrase", undefined), new $runtime.Choice(["which", "that"]), new $runtime.Choice(["is", "are"]), new $runtime.NonTerminal("apv_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, $0 : undefined, $1 : undefined, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_which_info_phrase", [new $runtime.NonTerminal("apv_filter", undefined), new $runtime.NonTerminal("two_which_info_phrase", ["functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void)])], ((filter : C.FilterSlot, table : D.ResultPhrase) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.declareSymbol("three_clean_info_phrase");
   $grammar.addRule("three_clean_info_phrase", [new $runtime.NonTerminal("apv_filter", undefined), new $runtime.NonTerminal("two_clean_info_phrase", ["functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void)])], ((filter : C.FilterSlot, table : D.ResultPhrase) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_clean_info_phrase", [new $runtime.NonTerminal("two_clean_info_phrase", undefined), new $runtime.NonTerminal("pvp_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
   $grammar.addRule("three_clean_info_phrase", [new $runtime.NonTerminal("two_clean_info_phrase", undefined), new $runtime.NonTerminal("preposition_filter", ["functionName" as ("functionName" extends keyof ReturnType<typeof C.filterKeyFn> ? string : void), 0, "functionName" as ("functionName" extends keyof ReturnType<typeof D.resultPhraseKeyFn> ? string : void)])], ((table : D.ResultPhrase, filter : C.FilterSlot) : (D.ResultPhrase)|null => D.addSlotToResultPhrase(table, filter)), D.resultPhraseKeyFn, {  });
};
