Wolfram mathematica 更改General::stop和主循环的行为

Wolfram mathematica 更改General::stop和主循环的行为,wolfram-mathematica,mathlink,Wolfram Mathematica,Mathlink,在General::stop的文档中,我们看到: 此消息是在 已生成指示消息 这是第三次单曲 评估 消息被抑制 防止重复或重复 长计算中的消息 我的问题是,在处理MathLink时,我将每个点作为一个单独的评估传递,因此General::stop永远不会出现 例如,如果我定义: link = LinkLaunch[First[$CommandLine] <> " -mathlink"] f[z_?NumericQ] := (Print@LinkRead[link]; Link

General::stop
的文档中,我们看到:

此消息是在 已生成指示消息 这是第三次单曲 评估

消息被抑制 防止重复或重复 长计算中的消息

我的问题是,在处理
MathLink
时,我将每个点作为一个单独的评估传递,因此
General::stop
永远不会出现

例如,如果我定义:

link = LinkLaunch[First[$CommandLine] <> " -mathlink"]
f[z_?NumericQ] := (Print@LinkRead[link]; 
   LinkWrite[link, 
    Unevaluated[
     EnterExpressionPacket[NIntegrate[Sin[1/x], {x, .001, z}]]]]; 
   While[Head[packet = LinkRead[link]] =!= OutputNamePacket, 
    Print[packet]]; First@LinkRead[link]);
Plot[f[z], {z, 1, 10}, PlotPoints -> 6, MaxRecursion -> 0]

因此问题仍然存在:如何在生成输出后禁用自动清除
$MessageList

可能有更好的解决方案,但这里有一个似乎有效的解决方案。据我所知,最重要的是在从内核中有一些持久变量来积累消息

link = LinkLaunch[First[$CommandLine] <> " -mathlink"]
f[z_?NumericQ] := 
(Print@LinkRead[link];
LinkWrite[link, Unevaluated[EnterExpressionPacket[
  If[! ValueQ[oldMessageList], oldMessageList = {}];
  Block[{$MessageList = oldMessageList},
   Module[{result},
    oldMessageList  = 
     Join[oldMessageList, (result = 
        NIntegrate[Sin[1/x], {x, .001, z}]; $MessageList)];
    result
    ]]]]];
While[Head[packet = LinkRead[link]] =!= OutputNamePacket, 
Print[packet]]; First@LinkRead[link]);

Plot[f[z], {z, 1, 10}, PlotPoints -> 6, MaxRecursion -> 0]
link=LinkLaunch[First[$CommandLine]“-mathlink”]
f[z_?NumericQ]:=
(Print@LinkRead[链接];
LinkWrite[链接,未评估的[输入表达式数据包][
如果[!ValueQ[oldMessageList],oldMessageList={}];
块[{$MessageList=oldMessageList},
模块[{result},
oldMessageList=
加入[oldMessageList,(结果=
第九个整体[Sin[1/x],{x,.001,z}];$MessageList];
结果
]]]]];
而[Head[packet=LinkRead[link]=!=outputnamepack,
打印[数据包];First@LinkRead[链接];
绘图[f[z],{z,1,10},绘图点->6,最大递归->0]

我找到了解决办法。它再次利用。这里是(当然,它必须在从内核中进行评估):

通过检查
$Line
的当前值并将其与以前的值进行比较,可以完全模拟从内核中消息的标准行为:

If[TrueQ[$Line > lastLine], 
 LinkWrite[$kern, 
  Unevaluated[ExpressionPacket[$globalMessageList = {};]]]; 
 LinkRead[$kern]]; lastLine = $Line;

:)

@Brett问题的根源是,从内核将所有计算视为单独的,并在每个计算之后清除
$MessageList
。它可能很容易模拟:
Unprotect[$MessageList];Do[$MessageList={};1/0,{20}]
。此代码不会停止生成相同的消息,并且不会出现
General::stop
。在
tutorial/Messages
页面上,我们看到:“在您进行的每一次计算中,Mathematica都会维护生成的所有消息的列表
$MessageList
。在标准Mathematica会话中,此列表在生成每一行输出后都会被清除。“这让我希望有一种方法可以创建一个非标准Mathematica会话,在该会话中,
$MessageList
不会在生成每一行输出后被清除。
$globalMessageList = {};
Unprotect[Message];
Message[args___] := 
  Block[{$inMsg = True, $MessageList = $globalMessageList},
    Message[args];
    $globalMessageList = $MessageList;
    ] /; ! TrueQ[$inMsg];
Protect[Message];
If[TrueQ[$Line > lastLine], 
 LinkWrite[$kern, 
  Unevaluated[ExpressionPacket[$globalMessageList = {};]]]; 
 LinkRead[$kern]]; lastLine = $Line;