作为ML {* ... *}命令的一部分,如何执行包含ML源的字符串?

时间:2014-04-11 08:08:58

标签: ml isabelle

来自Isabelle user list Makarius Wenzel说:

  

也可以在Isabelle / ML中将ML源作为字符串或标记传递,并在其上调用编译器。这是渐进式编译的正常好处。

我有一个ML语句作为字符串,如下所示:

ML{* val source_string = "val x = 3 + 4"; *}

我想在"val x = 3 + 4"命令中使用ML{*...*}作为ML语句。我可以通过外部调用Poly / ML来做到这一点:

ML{* 
fun polyp cmd = Isabelle_System.bash 
  ("perl -e 'print q(" ^ cmd ^ ");' | $ML_HOME/poly");
*}

ML{* polyp source_string; *}

大约需要200ms。如果我能在内部完成,我认为这将是大约0ms。

更新140411

Makarius Wenzel可能有另一种方法可以做,但我在ML_Context.eval_text下面的内容几乎就是我想要的。这符合我一直在试验的内容。问题是used_only_by_src1是全球性的。我不能把它放在let

我想如果我在两个不同的src1命令中使用ML{*...*},那么在used_only_by_src1被另一个使用之前可能会有一段很短的时间被ML{* val src1 = "x + y" (*I would actually have a global list of sources.*) val used_only_by_src1 = Unsynchronized.ref ""; fun two_int_arg_fun s1 s2 = let val s = "val x = " ^ s1 ^ "val y = " ^ s2 ^ "used_only_by_src1 := (Int.toString(" ^ src1 ^ "))"; val _ = ML_Context.eval_text true Position.none s; in !used_only_by_src1 end; *} ML{* two_int_arg_fun; two_int_arg_fun "44;" "778;" (*3ms*) *} 更改。但是,我想这是学习无状态编程的全部内容。

ML{*...*}

注意140412:实际上,我不需要执行ML字符串。我可以像普通一样在ML中编程,因为任何ML_Context.exec都可以访问全局ML函数,在那里我可以编写我需要的东西。

我从中得到的主要解决方案是如何将参数传递给Perl代码字符串,我从这里尝试为ML做这个,所以感谢davidg。另外,ML_Context.eval_textUnsynchronized.ref可能在某个地方有用,并且足够的学习能够使用它们非常有用。

存在需要本地或全局ML_Context.exec以保证不被其他代码(或非可变类型)更改的问题,但肯定有解决方案。

我没有追求Context.generic -> Context.generic因为isar_syn.ML对我没有任何意义,但我已经到了下面,所以现在我问,“我需要哪些功能涉及Toplevel.transition -> Toplevel.transition3+4,只要能够在ML{*...*}中获得Isabelle_System.bash的返回值,这对我有什么作用?

我在ML{* Isabelle_System.bash ("grep -nr 'get_generic' $ISABELLE_HOME/src/Pure"); Isabelle_System.bash ("grep -nr 'hash' $ML_HOME/../src/Basis/*"); Config.get_generic; (*From use at line 265 of isar_syn.ML.*) ML_Context.exec; ML_Context.exec (fn () => ML_Context.eval_text true Position.none "3 + 4"); (*OUT: val it = fn: Context.generic -> Context.generic*) (fn (txt, pos) => Toplevel.generic_theory (ML_Context.exec (fn () => ML_Context.eval_text true pos txt) #> Local_Theory.propagate_ml_env)) ("3 + 4", Position.none); (*OUT: val it = fn: Toplevel.transition -> Toplevel.transition*) *} 使用grep,在Isabelle / Pure中寻找正确的签名时,我已经得到了以下内容。我免费使用grep来寻找在Poly / ML Basis中寻找有用或需要的函数。

{{1}}

1 个答案:

答案 0 :(得分:0)

结构ML_Context可能是一个很好的起点。例如,您的表达式可以这样执行:

ML {*
  ML_Context.eval_text true Position.none "val x = 3 + 4"
*}

这将在内部评估表达式3 + 4,并丢弃结果。

ML_Context.exec等函数将允许您捕获表达式的结果并将它们放入本地上下文中;您可能希望查看MLsrc/Pure/Isar/isar_syn.ML Isar命令的实现,以了解在实践中如何使用这些函数。