List SML:扫描关系列表以获取所有可传递的关联

List SML:扫描关系列表以获取所有可传递的关联,list,sml,relation,smlnj,transitive-dependency,List,Sml,Relation,Smlnj,Transitive Dependency,我有一个环境列表,它保存变量和值之间的关联,例如env=[((“x”,1),(“y”,2),(“z”,3),…])。我还有另一个替换列表(由模式匹配控制函数返回),它保存变量和模式之间的关联,例如s=[(“v”,Var_p“z”),(“w”,Var_p“v”),(“u”,Var_p“w”),…]。让我们考虑第一对“代码>(V),VARYP P(Z))< /代码>:我的函数应该检查环境中对应于“代码>Z</CODE”的值,在 V和 Z < /代码>的值之间创建一个新的关联(即(v),3)< /代码

我有一个环境列表,它保存变量和值之间的关联,例如
env=[((“x”,1),(“y”,2),(“z”,3),…])
。我还有另一个替换列表(由模式匹配控制函数返回),它保存变量和模式之间的关联,例如
s=[(“v”,Var_p“z”),(“w”,Var_p“v”),(“u”,Var_p“w”),…]
。让我们考虑第一对“代码>(V),VARYP P(Z))< /代码>:我的函数应该检查环境中对应于“代码>Z</CODE”的值,在<代码> V和<代码> Z < /代码>的值之间创建一个新的关联(即<代码>(v),3)< /代码>,并将其放入环境中。我的这个函数代码如下

fun augment_env ([], e : env) = e
  | augment_env (s :: srest, e : env) =
     let
        val (a, b) = s
     in
        case b of
           Const_p i => [] @ augment_env_with_vars (srest, e)
         | Var_p x =>
            if (exists (e, x)) then (a, lookup (e, x)) :: augment_env_with_vars (srest, e)
     end;
这里,
s
是替换列表,
exists
lookup
是分别检查环境中是否存在变量和查找相应值的函数。此函数的问题在于,它仅适用于直接关联(在本例中,它将
v
3
之间的直接关联放入环境中)。它显然不适用于传递关联,除非我多次调用它(我事先不知道它们有多少)。回想一下这个例子,在这个函数结束时,我的环境列表应该是
env=[((“x”,1),(“y”,2),(“z”,3),(“v”,3),(“w”,3),(“u”,3),…]

您能给我一个关于如何修改此函数的提示,使其也能很好地处理传递关联吗


提前谢谢

首先,很难给出精确的提示,因为函数
lookup
使用变量
增强环境,并且某些类型是未知的

但是,根据您提供的信息,可以这样做:

取1

结果1

但是,如果替换列表中的任何变量位于其定义之前,
new_env
将失败。要解决此问题,只需在参考
lookup\u env
之前扫描替换列表:

第二次拍摄

结果2

注意第二个示例中交换的“u”和“w”

type const = int
type var = string
type env = (var * const) list
datatype value = Const_p of const | Var_p of var

exception Not_found

fun lookup_env (e, v) =
    case e of
        [] => raise Not_found
      | (a, b)::xs => if a = v then b else lookup_env (xs, v)

fun new_env (l, e) =
    case l of
        [] => e
      | (a, b)::xs =>
        case b of
            Const_p _ => new_env (xs, e)
          | Var_p b => new_env (xs, e @ [(a, lookup_env (e, b))])

(* test *)

val e = [("x", 1), ("y", 2), ("z", 3)]
val s = [("v", Var_p "z"), ("w", Var_p "v"), ("u", Var_p "w")]

val test = new_env (s, e)
val e = [("x",1),("y",2),("z",3)] : (string * int) list
val s = [("v",Var_p "z"),("w",Var_p "v"),("u",Var_p "w")]
  : (string * value) list
val test = [("x",1),("y",2),("z",3),("v",3),("w",3),("u",3)]
  : (var * int) list
fun lookup_var (l, v) =
    case l of
        [] => v
      | (a, b)::xs =>
        case b of
            Const_p _ => lookup_var (xs, v)
          | Var_p b => lookup_var (if a = v then (l, b) else (xs, v))

fun new_env2 (l, e) =
    case l of
        [] => e
      | (a, b)::xs =>
        case b of
            Const_p _ => new_env2 (xs, e)
          | Var_p b => new_env2 (xs, e @ [(a, lookup_env (e, lookup_var (l, b)))])

(* test *)

val e = [("x", 1), ("y", 2), ("z", 3)]
val s2 = [("v", Var_p "z"), ("u", Var_p "w"), ("w", Var_p "v")]

val test2 = new_env2 (s2, e)
val e = [("x",1),("y",2),("z",3)] : (string * int) list
val s2 = [("v",Var_p "z"),("u",Var_p "w"),("w",Var_p "v")]
  : (string * value) list
val test2 = [("x",1),("y",2),("z",3),("v",3),("u",3),("w",3)]
  : (var * int) list