来自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_text
和Unsynchronized.ref
可能在某个地方有用,并且足够的学习能够使用它们非常有用。
存在需要本地或全局ML_Context.exec
以保证不被其他代码(或非可变类型)更改的问题,但肯定有解决方案。
我没有追求Context.generic -> Context.generic
因为isar_syn.ML对我没有任何意义,但我已经到了下面,所以现在我问,“我需要哪些功能涉及Toplevel.transition -> Toplevel.transition
或3+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}}
答案 0 :(得分:0)
结构ML_Context
可能是一个很好的起点。例如,您的表达式可以这样执行:
ML {*
ML_Context.eval_text true Position.none "val x = 3 + 4"
*}
这将在内部评估表达式3 + 4
,并丢弃结果。
ML_Context.exec
等函数将允许您捕获表达式的结果并将它们放入本地上下文中;您可能希望查看ML
中src/Pure/Isar/isar_syn.ML
Isar命令的实现,以了解在实践中如何使用这些函数。