// From code.ys.def:
OMDef("Limit", "limit1","limit",
      {  _0, _2, OMS("limit1", "under"), OMBIND(OMS("fns1", "lambda"), OMBVAR(_1), _4) }_(_3=Left)
      |{ _0, _2, OMS("limit1", "above"), OMBIND(OMS("fns1", "lambda"), OMBVAR(_1), _4) }_(_3=Right)
      |{ _0, _2, OMS("limit1", "both_sides"), OMBIND(OMS("fns1", "lambda"), OMBVAR(_1), _3) },
      { _0, _{3,2,1}, _1, Left,  _{3,3}}_(_2=OMS("limit1", "below"))
      |{_0, _{3,2,1}, _1, Right, _{3,3}}_(_2=OMS("limit1", "above"))
      |{_0, _{3,2,1}, _1, _{3,3}}
     );
// Test [result Limit(x,0,Right)1/x]: FromString(ToString()OMForm(Limit(x,0,Right) 1/x))OMRead()

// As explained in the manual, "limit1:both_sides" and "fns1:lambda" will
// be handled as OMS("limit1", "both_sides") and OMS("fns1", "lambda"), so
// we don't need to define bogus mappings for them:
// OMDef("OMSymbolLimit1BothSides", "limit1", "both_sides");
// OMDef("OMSymbolLambda", "fns1", "lambda");
// The same applies to "Left" and "Right", which are undefined symbols
// that are used only inside limit expressions, so they don't need a mapping
// of their own.
// We could define them as follows:
//OMDef("Left",  "limit1","below");
//OMDef("Right", "limit1","above");
// and then use the following rules instead:
//      {  _0, _2, Left,  OMBIND(OMS("fns1", "lambda"), OMBVAR(_1), _4) }_(_3=Left)
//      |{ _0, _2, Right, OMBIND(OMS("fns1", "lambda"), OMBVAR(_1), _4) }_(_3=Right)
//      |{ _0, _2, OMS("limit1", "both_sides"), OMBIND(OMS("fns1", "lambda"), OMBVAR(_1), _3) },
//      { _0, _{3,2,1}, _1, _2, _{3,3}}_(_2=Left Or _2=Right)
//      |{_0, _{3,2,1}, _1, _{3,3}}
// The result is exactly the same. The only difference is when producing the
// OMForm of the symbols themselves, outside the limit expression.
