Семантические правила в Scala

#scala #pattern-matching #semantics

#scala #сопоставление с образцом #семантика

Вопрос:

Здесь я написал код из двух правил, связанных с обработкой сред в Scala. В коде все работает отлично, однако я не слишком уверен в определениях, которые я написал, чтобы объяснить, что происходит за капотом. Я не уверен, может ли кто-нибудь проверить мои правила на правильность? Я не уверен в переводе семантических правил. Для второго правила я понимаю, что недопустимая переменная приведет к оценке ошибки. Мне не ясно, в каком правиле 1 должно быть определено.

Правило 1: введите описание изображения здесьПравило 2: введите описание изображения здесь

 sealed trait Environment 
sealed trait Value

case object EmptyEnv extends Environment
case class Extend(x: String, v: Value, sigma: Environment) extends Environment
case class ExtendRec(f: String, x: String, e: Expr, sigma: Environment ) extends Environment
case class ExtendMutualRec2(f1: String, x1: String, e1: Expr, f2: String, x2: String, e2: Expr, sigma: Environment) extends Environment 

/* -- We need to redefine values to accomodate the new representation of environments --*/
case class NumValue(d: Double) extends Value
case class BoolValue(b: Boolean) extends Value
case class Closure(x: String, e: Expr, pi: Environment) extends Value
case object ErrorValue extends Value


/*2. Operators on values */

def valueToNumber(v: Value): Double = v match {
    case NumValue(d) => d
    case _ => throw new IllegalArgumentException(s"Error: Asking me to convert Value: $v to a number")
}

def valueToBoolean(v: Value): Boolean = v match {
    case BoolValue(b) => b
    case _ => throw new IllegalArgumentException(s"Error: Asking me to convert Value: $v to a boolean")
}

def valueToClosure(v: Value): Closure = v match {
    case Closure(x, e, pi) => Closure(x, e, pi)
    case _ =>  throw new IllegalArgumentException(s"Error: Asking me to convert Value: $v to a closure")
}


/*-- Operations on environments --*/

def lookupEnv(sigma: Environment, x: String): Value = sigma match {
    case EmptyEnv => throw new IllegalArgumentException(s"Error could not find string $x in environment")
    case Extend(y, v, _) if y == x => v
    case Extend(_, _, pi) => lookupEnv(pi, x)
    case ExtendRec(f, y, e, pi) => if (x == f) 
                                          Closure(y, e, sigma)
                                   else
                                          lookupEnv(pi, x)
    case ExtendMutualRec2(f1, x1, e1, f2, x2, e2, pi ) => 
    {
        if (x == f1)
            Closure(x1, e1, sigma)
        else if (x == f2)
            Closure(x2, e2, sigma)
        else 
            lookupEnv(pi, x)
    }
}
  
 case class Seq(e1: Expr, e2: Expr) extends Expr
....
....
case Seq(e1, e2) => {
            val (v1, store1) = evalExpr(e1, env, store)
            val (v2, store2) = evalExpr(e2, env, store1)
            (v2, store2)
            
        }
  

Комментарии:

1. Вашему вопросу не хватает некоторого контекста. Вероятно, перед взаимной рекурсией вы выполняли обычную рекурсию и нерекурсивную let .

2. @DmytroMitin заранее извиняется. Я не хотел перегружать контент, полагая, что то, чего мне не хватает, очевидно. Это правильно. Пусть было предыдущим

3. Вы не указали Expr иерархию. Что такое подпись evalExpr ? Вы могли бы попробовать написать тестовую программу с взаимной рекурсией на вашем языке (например isOdd: Num -> Bool , isEven: Num -> Bool ) и посмотреть, правильно ли она оценена.

4. На первом скриншоте eval есть два параметра (выражение и среда), на втором — три параметра.

5. Вы нашли ответы на свои вопросы?

Ответ №1:

Что касается правила 1, кажется, вам следует добавить еще один случай к вашему оценщику

 def evalExpr(e: Expr, env: Environment, store: ???): (Value, ???) = e match {
  //...
  case Seq(e1, e2) =>
    val (v1, store1) = evalExpr(e1, env, store)
    val (v2, store2) = evalExpr(e2, env, store1) // what if v1 = error?
    (v2, store2)

  case LetRec2(f1, x1, e1, f2, x2, e2, env) =>
    evalExpr(e, ExtendMutualRec2(f1, x1, e1, f2, x2, e2, env), store /*???*/)
}