// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*-
//
// This file is part of Genie
//
// Copyright 2019-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>

import assert from 'assert';
import { Ast, Type } from 'thingtalk';
import * as C from '../ast_manip';
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("constant_Number");
   if (!$options.flags.inference) {
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Number", ["zero"], (($0 : undefined) : (Ast.NumberValue)|null => new Ast.Value.Number(0)), C.entityOrNumberValueKeyFn, {  });
           $grammar.addRule("constant_Number", ["one"], (($0 : undefined) : (Ast.NumberValue)|null => new Ast.Value.Number(1)), C.entityOrNumberValueKeyFn, {  });
       }
   }
   $grammar.declareSymbol("constant_date_point");
   $grammar.addRule("constant_date_point", ["now"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(null, '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_date_point", ["today"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.DateEdge('start_of', 'day'), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_date_point", ["yesterday"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.DateEdge('start_of', 'day'), '-', new Ast.Value.Measure(1, 'day'))), C.valueKeyFn, {  });
   if (!$options.flags.turking) {
       if ($options.flags.future_dates) {
           $grammar.addRule("constant_date_point", ["tomorrow"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.DateEdge('end_of', 'day'), '+', null)), C.valueKeyFn, {  });
           $grammar.addRule("constant_date_point", ["the end of the day"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.DateEdge('end_of', 'day'), '+', null)), C.valueKeyFn, {  });
           $grammar.addRule("constant_date_point", ["the end of the week"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.DateEdge('end_of', 'week'), '+', null)), C.valueKeyFn, {  });
           $grammar.addRule("constant_date_point", ["the end of the month"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.DateEdge('end_of', 'mon'), '+', null)), C.valueKeyFn, {  });
           $grammar.addRule("constant_date_point", ["the end of the year"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.DateEdge('end_of', 'year'), '+', null)), C.valueKeyFn, {  });
       }
   }
   $grammar.declareSymbol("constant_date_range");
   $grammar.addRule("constant_date_range", ["this week"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => [C.makeDate(new Ast.DateEdge('start_of', 'week'), '+', null), C.makeDate(new Ast.DateEdge('end_of', 'week'), '+', null)]), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["this month"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => [C.makeDate(new Ast.DateEdge('start_of', 'mon'), '+', null), C.makeDate(new Ast.DateEdge('end_of', 'mon'), '+', null)]), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["this year"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => [C.makeDate(new Ast.DateEdge('start_of', 'year'), '+', null), C.makeDate(new Ast.DateEdge('end_of', 'year'), '+', null)]), C.valueArrayKeyFn, {  });
   if (!$options.flags.turking) {
       $grammar.addRule("constant_date_range", ["last week"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => [C.makeDate(new Ast.DateEdge('start_of', 'week'), '-', new Ast.Value.Measure(1, 'week')), C.makeDate(new Ast.DateEdge('start_of', 'week'), '+', null)]), C.valueArrayKeyFn, {  });
       $grammar.addRule("constant_date_range", ["last month"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => [C.makeDate(new Ast.DateEdge('start_of', 'mon'), '-', new Ast.Value.Measure(1, 'mon')), C.makeDate(new Ast.DateEdge('start_of', 'mon'), '+', null)]), C.valueArrayKeyFn, {  });
       $grammar.addRule("constant_date_range", ["last year"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => [C.makeDate(new Ast.DateEdge('start_of', 'year'), '-', new Ast.Value.Measure(1, 'year')), C.makeDate(new Ast.DateEdge('start_of', 'year'), '+', null)]), C.valueArrayKeyFn, {  });
       if ($options.flags.future_dates) {
           $grammar.addRule("constant_date_range", ["next week"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => [C.makeDate(new Ast.DateEdge('end_of', 'week'), '+', null), C.makeDate(new Ast.DateEdge('end_of', 'week'), '+', new Ast.Value.Measure(1, 'week'))]), C.valueArrayKeyFn, {  });
           $grammar.addRule("constant_date_range", ["next month"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => [C.makeDate(new Ast.DateEdge('end_of', 'mon'), '+', null), C.makeDate(new Ast.DateEdge('end_of', 'mon'), '+', new Ast.Value.Measure(1, 'mon'))]), C.valueArrayKeyFn, {  });
           $grammar.addRule("constant_date_range", ["next year"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => [C.makeDate(new Ast.DateEdge('end_of', 'year'), '+', null), C.makeDate(new Ast.DateEdge('end_of', 'year'), '+', new Ast.Value.Measure(1, 'year'))]), C.valueArrayKeyFn, {  });
       }
       $grammar.addRule("constant_date_range", [new $runtime.NonTerminal("constant_Number", undefined)], ((year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => {
            if (year.value <= 0)
                return null;
            return [
                C.makeDate(new Date(C.fixTwoYearNumber(year.value), 0), '+', null),
                C.makeDate(new Date(C.fixTwoYearNumber(year.value), 0), '+', new Ast.Value.Measure(1, 'year'))
            ];
        }), C.valueArrayKeyFn, {  });
       $grammar.addRule("constant_date_range", [new $runtime.NonTerminal("constant_Number", undefined), "s"], ((year : Ast.NumberValue, $0 : undefined) : ([Ast.Value, Ast.Value])|null => {
            if (year.value <= 0)
                return null;
            return [
                C.makeDate(new Date(C.fixTwoYearNumber(year.value), 0), '+', null),
                C.makeDate(new Date(C.fixTwoYearNumber(year.value), 0), '+', new Ast.Value.Measure(10, 'year'))
            ];
        }), C.valueArrayKeyFn, {  });
   }
   $grammar.addRule("constant_date_range", ["jan"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 1)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["january"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 1)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["jan", "january"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 1)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["feb"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 2)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["february"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 2)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["feb", "february"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 2)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["mar"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 3)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["march"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 3)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["mar", "march"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 3)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["apr"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 4)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["april"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 4)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["apr", "april"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 4)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["may"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 5)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["may of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 5)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["jun"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 6)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["june"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 6)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["jun", "june"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 6)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["jul"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 7)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["july"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 7)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["jul", "july"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 7)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["aug"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 8)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["august"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 8)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["aug", "august"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 8)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["sep"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 9)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["sept"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 9)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["september"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 9)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["sep", "sept", "september"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 9)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["oct"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 10)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["october"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 10)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["oct", "october"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 10)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["nov"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 11)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["november"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 11)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["nov", "november"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 11)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["dec"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 12)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", ["december"], (($0 : undefined) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(null, 12)), C.valueArrayKeyFn, {  });
   $grammar.addRule("constant_date_range", [new $runtime.Choice(["dec", "december"]), "of", new $runtime.NonTerminal("constant_Number", undefined)], (($0 : undefined, $1 : undefined, year : Ast.NumberValue) : ([Ast.Value, Ast.Value])|null => C.makeMonthDateRange(year.value, 12)), C.valueArrayKeyFn, {  });
   $grammar.declareSymbol("constant_day_of_week");
   $grammar.addRule("constant_day_of_week", ["mon"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('monday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["monday"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('monday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["last", new $runtime.Choice(["mon", "monday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('monday', null), '-', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["next", new $runtime.Choice(["mon", "monday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('monday', null), '+', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["tue"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('tuesday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["tuesday"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('tuesday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["last", new $runtime.Choice(["tue", "tuesday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('tuesday', null), '-', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["next", new $runtime.Choice(["tue", "tuesday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('tuesday', null), '+', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["wed"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('wednesday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["wednesday"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('wednesday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["last", new $runtime.Choice(["wed", "wednesday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('wednesday', null), '-', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["next", new $runtime.Choice(["wed", "wednesday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('wednesday', null), '+', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["thu"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('thursday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["thursday"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('thursday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["last", new $runtime.Choice(["thu", "thursday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('thursday', null), '-', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["next", new $runtime.Choice(["thu", "thursday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('thursday', null), '+', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["fri"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('friday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["friday"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('friday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["last", new $runtime.Choice(["fri", "friday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('friday', null), '-', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["next", new $runtime.Choice(["fri", "friday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('friday', null), '+', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["sat"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('saturday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["saturday"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('saturday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["last", new $runtime.Choice(["sat", "saturday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('saturday', null), '-', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["next", new $runtime.Choice(["sat", "saturday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('saturday', null), '+', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["sun"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('sunday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["sunday"], (($0 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('sunday', null), '+', null)), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["last", new $runtime.Choice(["sun", "sunday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('sunday', null), '-', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.addRule("constant_day_of_week", ["next", new $runtime.Choice(["sun", "sunday"])], (($0 : undefined, $1 : undefined) : (Ast.Value)|null => C.makeDate(new Ast.WeekDayDate('sunday', null), '+', new Ast.Value.Measure(1, 'week'))), C.valueKeyFn, {  });
   $grammar.declareSymbol("constant_Date");
   if (!$options.flags.inference) {
       $grammar.addRule("constant_Date", [new $runtime.NonTerminal("constant_date_point", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       $grammar.addRule("constant_Date", [new $runtime.NonTerminal("constant_day_of_week", undefined)], (($0 : Ast.Value) : (Ast.Value)|null => { return $0; }), C.valueKeyFn, { identity: (true) });
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Date", [new $runtime.NonTerminal("constant_Measure_ms", undefined), "ago"], ((duration : Ast.Value, $0 : undefined) : (Ast.Value)|null => C.makeDate(null, '-', duration)), C.valueKeyFn, {  });
           $grammar.addRule("constant_Date", [new $runtime.NonTerminal("constant_Measure_ms", undefined), "before", new $runtime.NonTerminal("constant_date_point", undefined)], ((duration : Ast.Value, $0 : undefined, pt : Ast.Value) : (Ast.Value)|null => C.makeDate(pt, '-', duration)), C.valueKeyFn, {  });
           if ($options.flags.future_dates) {
               $grammar.addRule("constant_Date", [new $runtime.NonTerminal("constant_Measure_ms", undefined), "from now"], ((duration : Ast.Value, $0 : undefined) : (Ast.Value)|null => C.makeDate(null, '+', duration)), C.valueKeyFn, {  });
               $grammar.addRule("constant_Date", [new $runtime.NonTerminal("constant_Measure_ms", undefined), "after", new $runtime.NonTerminal("constant_date_point", undefined)], ((duration : Ast.Value, $0 : undefined, pt : Ast.Value) : (Ast.Value)|null => C.makeDate(pt, '+', duration)), C.valueKeyFn, {  });
           }
       }
   }
   $grammar.declareSymbol("constant_Measure_ms");
   if (!$options.flags.inference) {
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "ms"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('ms', num)), C.valueKeyFn, {  });
       }
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "milliseconds"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('ms', num)), C.valueKeyFn, {  });
       }
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "s"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('s', num)), C.valueKeyFn, {  });
       }
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "seconds"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('s', num)), C.valueKeyFn, {  });
       }
       $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "min"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('min', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "minutes"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('min', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "h"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('h', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "hours"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('h', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "days"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('day', num)), C.valueKeyFn, {  });
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "weeks"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('week', num)), C.valueKeyFn, {  });
       }
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "months"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('mon', num)), C.valueKeyFn, {  });
       }
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_ms", [new $runtime.NonTerminal("constant_Number", undefined), "years"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('year', num)), C.valueKeyFn, {  });
       }
   }
   $grammar.declareSymbol("constant_Measure_byte");
   if (!$options.flags.inference) {
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_byte", [new $runtime.NonTerminal("constant_Number", undefined), "byte"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('byte', num)), C.valueKeyFn, {  });
       }
       $grammar.addRule("constant_Measure_byte", [new $runtime.NonTerminal("constant_Number", undefined), "kb"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('KB', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_byte", [new $runtime.NonTerminal("constant_Number", undefined), "mb"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('MB', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_byte", [new $runtime.NonTerminal("constant_Number", undefined), "gb"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('GB', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_byte", [new $runtime.NonTerminal("constant_Number", undefined), "tb"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('TB', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_byte", [new $runtime.NonTerminal("constant_Number", undefined), "kilobytes"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('KB', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_byte", [new $runtime.NonTerminal("constant_Number", undefined), "megabytes"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('MB', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_byte", [new $runtime.NonTerminal("constant_Number", undefined), "gigabytes"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('GB', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_byte", [new $runtime.NonTerminal("constant_Number", undefined), "terabytes"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('TB', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_kg");
   if (!$options.flags.inference) {
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_kg", [new $runtime.NonTerminal("constant_Number", undefined), "grams"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('g', num)), C.valueKeyFn, {  });
       }
       $grammar.addRule("constant_Measure_kg", [new $runtime.NonTerminal("constant_Number", undefined), "kilograms"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('kg', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_kg", [new $runtime.NonTerminal("constant_Number", undefined), "kg"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('kg', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_kg", [new $runtime.NonTerminal("constant_Number", undefined), "pounds"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('lb', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_kg", [new $runtime.NonTerminal("constant_Number", undefined), "lbs"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('lb', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_kg", [new $runtime.NonTerminal("constant_Number", undefined), "ounces"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('oz', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_kg", [new $runtime.NonTerminal("constant_Number", undefined), "oz"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('oz', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_C");
   if (!$options.flags.inference) {
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_C", [new $runtime.NonTerminal("constant_Number", undefined), "c"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('C', num)), C.valueKeyFn, {  });
           $grammar.addRule("constant_Measure_C", [new $runtime.NonTerminal("constant_Number", undefined), "centigrade"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('C', num)), C.valueKeyFn, {  });
       }
       $grammar.addRule("constant_Measure_C", [new $runtime.NonTerminal("constant_Number", undefined), "f"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('F', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_C", [new $runtime.NonTerminal("constant_Number", undefined), "fahrenheit"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('F', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_C", [new $runtime.NonTerminal("constant_Number", undefined), "degrees"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('defaultTemperature', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_m");
   if (!$options.flags.inference) {
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_m", [new $runtime.NonTerminal("constant_Number", undefined), "m"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('m', num)), C.valueKeyFn, {  });
       }
       $grammar.addRule("constant_Measure_m", [new $runtime.NonTerminal("constant_Number", undefined), "meters"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('m', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m", [new $runtime.NonTerminal("constant_Number", undefined), "km"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('km', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m", [new $runtime.NonTerminal("constant_Number", undefined), "kilometers"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('km', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m", [new $runtime.NonTerminal("constant_Number", undefined), "mi"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('mi', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m", [new $runtime.NonTerminal("constant_Number", undefined), "miles"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('mi', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m", [new $runtime.NonTerminal("constant_Number", undefined), "ft"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('ft', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m", [new $runtime.NonTerminal("constant_Number", undefined), "in"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('in', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m", [new $runtime.NonTerminal("constant_Number", undefined), "inches"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('in', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m", [new $runtime.NonTerminal("constant_Number", undefined), "cm"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('cm', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_m2");
   if (!$options.flags.inference) {
       $grammar.addRule("constant_Measure_m2", [new $runtime.NonTerminal("constant_Number", undefined), "square meters"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('m2', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m2", [new $runtime.NonTerminal("constant_Number", undefined), "square km"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('km2', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m2", [new $runtime.NonTerminal("constant_Number", undefined), "square kilometers"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('km2', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m2", [new $runtime.NonTerminal("constant_Number", undefined), "square ft"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('ft2', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m2", [new $runtime.NonTerminal("constant_Number", undefined), "square feet"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('ft2', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_m3");
   if (!$options.flags.inference) {
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "cubic meters"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('m3', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "cubic km"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('km3', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "cubic kilometers"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('km3', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "cubic ft"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('ft3', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "cubic feet"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('ft3', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "liter"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('l', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "l"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('l', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "cl"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('cl', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "hl"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('hl', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "ml"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('ml', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "floz"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('floz', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "gallon"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('gal', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "quart"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('qt', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "pint"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('pint', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "cup"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('cup', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "teaspoon"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('tsp', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_m3", [new $runtime.NonTerminal("constant_Number", undefined), "tablespoon"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('tbsp', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_mps");
   if (!$options.flags.inference) {
       $grammar.addRule("constant_Measure_mps", [new $runtime.NonTerminal("constant_Number", undefined), "mph"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('mph', num)), C.valueKeyFn, {  });
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Measure_mps", [new $runtime.NonTerminal("constant_Number", undefined), "m/s"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('mps', num)), C.valueKeyFn, {  });
       }
       $grammar.addRule("constant_Measure_mps", [new $runtime.NonTerminal("constant_Number", undefined), "kph"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('kmph', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_mps", [new $runtime.NonTerminal("constant_Number", undefined), "miles per hour"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('mph', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_mps", [new $runtime.NonTerminal("constant_Number", undefined), "kilometers per hour"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('kmph', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_mps", [new $runtime.NonTerminal("constant_Number", undefined), "km/h"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('kmph', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_W");
   if (!$options.flags.inference) {
       $grammar.addRule("constant_Measure_W", [new $runtime.NonTerminal("constant_Number", undefined), "w"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('W', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_W", [new $runtime.NonTerminal("constant_Number", undefined), "watt"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('W', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_W", [new $runtime.NonTerminal("constant_Number", undefined), "kw"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('kW', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_W", [new $runtime.NonTerminal("constant_Number", undefined), "kilowatt"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('W', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_lx");
   if (!$options.flags.inference) {
       $grammar.addRule("constant_Measure_lx", [new $runtime.NonTerminal("constant_Number", undefined), "lx"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('lx', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_lm");
   if (!$options.flags.inference) {
       $grammar.addRule("constant_Measure_lm", [new $runtime.NonTerminal("constant_Number", undefined), "lm"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('lm', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_dB");
   if (!$options.flags.inference) {
       $grammar.addRule("constant_Measure_dB", [new $runtime.NonTerminal("constant_Number", undefined), "db"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('dB', num)), C.valueKeyFn, {  });
       $grammar.addRule("constant_Measure_dB", [new $runtime.NonTerminal("constant_Number", undefined), "decibels"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('dB', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Measure_dBm");
   if (!$options.flags.inference) {
       $grammar.addRule("constant_Measure_dBm", [new $runtime.NonTerminal("constant_Number", undefined), "dbm"], ((num : Ast.NumberValue, $0 : undefined) : (Ast.Value)|null => C.addUnit('dBm', num)), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_Location");
   if (!$options.flags.inference) {
       $grammar.addRule("constant_Location", ["here"], (($0 : undefined) : (Ast.LocationValue)|null => new Ast.Value.Location(new Ast.Location.Relative('current_location'))), C.valueKeyFn, {  });
       if (!$options.flags.turking) {
           $grammar.addRule("constant_Location", ["where i am now"], (($0 : undefined) : (Ast.LocationValue)|null => new Ast.Value.Location(new Ast.Location.Relative('current_location'))), C.valueKeyFn, {  });
       }
       $grammar.addRule("constant_Location", ["the area"], (($0 : undefined) : (Ast.LocationValue)|null => new Ast.Value.Location(new Ast.Location.Relative('current_location'))), C.valueKeyFn, {  });
       $grammar.addRule("constant_Location", ["the city"], (($0 : undefined) : (Ast.LocationValue)|null => new Ast.Value.Location(new Ast.Location.Relative('current_location'))), C.valueKeyFn, {  });
       $grammar.addRule("constant_Location", ["home"], (($0 : undefined) : (Ast.LocationValue)|null => new Ast.Value.Location(new Ast.Location.Relative('home'))), C.valueKeyFn, {  });
       $grammar.addRule("constant_Location", ["my home"], (($0 : undefined) : (Ast.LocationValue)|null => new Ast.Value.Location(new Ast.Location.Relative('home'))), C.valueKeyFn, {  });
       $grammar.addRule("constant_Location", ["my neighborhood"], (($0 : undefined) : (Ast.LocationValue)|null => new Ast.Value.Location(new Ast.Location.Relative('home'))), C.valueKeyFn, {  });
       $grammar.addRule("constant_Location", ["work"], (($0 : undefined) : (Ast.LocationValue)|null => new Ast.Value.Location(new Ast.Location.Relative('work'))), C.valueKeyFn, {  });
       $grammar.addRule("constant_Location", ["my office"], (($0 : undefined) : (Ast.LocationValue)|null => new Ast.Value.Location(new Ast.Location.Relative('work'))), C.valueKeyFn, {  });
       $grammar.addRule("constant_Location", ["my workplace"], (($0 : undefined) : (Ast.LocationValue)|null => new Ast.Value.Location(new Ast.Location.Relative('work'))), C.valueKeyFn, {  });
   }
   $grammar.declareSymbol("constant_pairs");
   $grammar.addRule("constant_pairs", [new $runtime.NonTerminal("constant_Any", undefined), "and", new $runtime.NonTerminal("constant_Any", ["type" as ("type" extends keyof ReturnType<typeof C.valueKeyFn> ? string : void), 0, "type" as ("type" extends keyof ReturnType<typeof C.valueKeyFn> ? string : void)])], ((c1 : Ast.Value, $0 : undefined, c2 : Ast.Value) : ([Ast.Value, Ast.Value])|null => {
        assert(c1.getType().equals(c2.getType()));
        if (c1.equals(c2))
            return null;
        return [c1, c2];
    }), C.valueArrayKeyFn, {  });
   $grammar.declareSymbol("constant_or_pairs");
   $grammar.addRule("constant_or_pairs", [new $runtime.NonTerminal("constant_Any", undefined), "or", new $runtime.NonTerminal("constant_Any", ["type" as ("type" extends keyof ReturnType<typeof C.valueKeyFn> ? string : void), 0, "type" as ("type" extends keyof ReturnType<typeof C.valueKeyFn> ? string : void)])], ((c1 : Ast.Value, $0 : undefined, c2 : Ast.Value) : ([Ast.Value, Ast.Value])|null => {
        assert(c1.getType().equals(c2.getType()));
        if (c1.equals(c2))
            return null;
        return [c1, c2];
    }), C.valueArrayKeyFn, {  });
   $grammar.declareSymbol("constant_nor_pairs");
   $grammar.addRule("constant_nor_pairs", [new $runtime.NonTerminal("constant_Any", undefined), "nor", new $runtime.NonTerminal("constant_Any", ["type" as ("type" extends keyof ReturnType<typeof C.valueKeyFn> ? string : void), 0, "type" as ("type" extends keyof ReturnType<typeof C.valueKeyFn> ? string : void)])], ((c1 : Ast.Value, $0 : undefined, c2 : Ast.Value) : ([Ast.Value, Ast.Value])|null => {
        assert(c1.getType().equals(c2.getType()));
        if (c1.equals(c2))
            return null;
        return [c1, c2];
    }), C.valueArrayKeyFn, {  });
   $grammar.declareSymbol("constant_String_ContextRef");
   if ($options.flags.screen_selection) {
       $grammar.addRule("constant_String_ContextRef", ["this"], (($0 : undefined) : (Ast.ContextRefValue)|null => new Ast.Value.ContextRef('selection', Type.String)), C.valueKeyFn, {  });
   }
   if ($options.flags.screen_selection) {
       $grammar.addRule("constant_String_ContextRef", ["the selection on the screen"], (($0 : undefined) : (Ast.ContextRefValue)|null => new Ast.Value.ContextRef('selection', Type.String)), C.valueKeyFn, {  });
   }
};
