没有合适的资源?快使用搜索试试~ 我知道了~
互动式咖喱观察绘图仪iCODE:一种用于调试和学习的工具
--理论计算机科学电子笔记177(2007)107-122www.elsevier.com/locate/entcs互动式咖喱观察绘图仪iCODE1帕里萨·H Sadeghi和Frank Huchphsa,informatik.uni-kiel.de基尔大学计算机科学学院奥尔绍森海峡 40,24098 Kiel,Germany摘要通过观察表达式和函数的求值来查找bug是一种有用的方法在惰性函数和函数逻辑程序中。 但是,添加和移除观测注记是一种使这种调试技术的使用在实践中不舒服的尝试。具有用于管理观测的工具支持是期望的。我们开发了一个工具,为程序员提供这种能力。 在程序中没有注释表达式的情况下,函数、数据结构和任意子表达式的求值可以通过从表示整个程序的树结构中选择它们来观察。 此外,该工具提供了一个逐步执行的观察,其中每个观察显示在单独的视图中。 除了搜索bug外,该工具还可以用于帮助初学者学习惰性函数逻辑程序的非确定性行为。 为了找到包含故障的周围区域,该工具还可以通过标记表达式来显示程序的执行部分在程序执行期间被激活关键词:Curry,调试,函数逻辑语言,观察,工具1引言编程的一个原始问题是定位程序中的错误。 这对于声明性编程语言尤其如此,这使得预测求值顺序变得困难。 有很多方法可以定位程序中的bug(相关的方法在第7节中讨论)。尽管实现这些方法的工具通常不能删除bug,但它们通常被称为调试器。Curry Object Observation System(COOSY)是其中之一[2]。 这个调试器是一个工具,用于观察用声明性多范式语言Curry编写的程序的数据结构和函数[9]。COOSY扩展了吉尔[1]在惰性函数式程序中观察表达式到惰性函数式逻辑设置。1这项工作得到了德国研究委员会(DFG)的部分支持,基金编号为Ha 2457/5-1。1571-0661 © 2007 Elsevier B. V.在CC BY-NC-ND许可下开放访问。doi:10.1016/j.entcs.2007.01.007108P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107在COOSY中,程序员在她/他的程序中注释表达式,以观察程序在所需位置执行的评估然而,在实践中,在程序中添加和删除观察结果是某种让人们远离使用COOSY等工具的方法相反,人们更喜欢使用跟踪打印数据结构,这会影响求值行为,并且不提供观察函数的能力对于仍然在与类型系统、curry和惰性求值作斗争的初学者来说,另一个问题存在:理解COOSY对他们来说意味着另一个负担(特别是因为Curry没有提供类型类,并且必须使用与观察值的类型相关的特殊观察者来注释观察我们的解决方案是一个方便的图形交互式工具,称为iCODE(交互式咖喱观察调试器),它支持通过观察进行调试,具有以下功能:• 标记表示程序的执行部分的表达式以定位包含故障的周围区域• 将整个程序表示为具有对图形用户界面中的每个表达式或函数• 在分离的观看者中显示节目的每个期望部分的观察步骤,具有在步骤上的向后和向前步进能力• 自动生成所有用户定义的数据类型的观察者所有的源代码修改都是在执行代码之前自动执行的在一个单独的窗口中一步一步地展示所选数据结构或函数的评估,可以帮助初学者理解Curry的延迟该演示文稿提供了另一个优点:所有视图都是由独立的系统进程实现的,这些进程甚至可以分布在多台计算机上,以避免观察到的执行的内存变慢或短缺最后,可以保存观察会话,并在需要再次调试时重新加载。该工具在Curry中使用用于GUI编程[10,11]和Curry系统PAKCS [6]可用的Meta编程的库来第二章对COOSYCOOSY [2]基于在程序执行期间观察数据结构和函数的思想。程序员可以将模块Observe导入到她/他的程序中,并使用函数observe的应用程序注释表达式:observe:: Observer a -> String -> a -> a函数observe在其第三个参数上表现为一个恒等式。此外,它还生成一个表示观察数据的评估部分的跟踪文件,作为隐藏的侧面效果。为了区分不同的观察,观察需要一个标签作为它的第二个参数。在程序终止(包括运行时错误和中止)后,所有观察结果都以不同的标签显示给用户最后,observe需要一个观察者作为它的第一个论证P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107109它定义了所观察到的值的类型的特殊观察行为对于每一个预先定义的类型τ,这样的观察者被定义为oτ。例如,对于Int类型的表达式,应该使用observeroInt,而对于[Int],应该使用observer oList oInt。注意,多态类型构造函数的观察者(例如,[])是接受与类型构造函数一样多的参数的函数。每种类型的观察者的显式注释是必要的,因为Curry,与Haskell相反,它不提供类型类,在HOOD中对用户隐藏这些观察者。然而,这些明确的注释也有好处。可以对同一类型使用不同的观察器,这允许在大型观察数据结构中选择性地屏蔽子结构,例如通过预定义的观察器oOpaque[2],它通过符号#表示每个数据结构。作为一个小例子,我们考虑一个函数,它计算给定列表的所有子列表(这里的元素类型为Int):子列表::[Int] ->[[Int]]子列表xs =let(ready,extend)=子列表sublists子列表sublists(ready++extend,[x]:map(x:)extend)这个想法是为了区分已经关闭的子列表和可以用实际列表元素x扩展的列表。不幸的是,这个程序包含一个小bug。子列表[1,2,3]产生:[[],[],[3],[3],[2],[2,3],[2,3],[1],[1,2],[1,2,3],[1,2,3]]某些元素在结果中出现两次。为了找到这个bug,我们首先观察子列表子列表xs=let(ready,extend)=observe(oPair(oList(oList oInt))(oList(oListoInt)“result”(sublists'xs)inready++扩展结果([[],[],[3],[3],[2],[2,3],[2,3]],[[1],[1,2],[1,2,3],[1,2,3]])这个bug似乎是由第一个pair组件引起的,因为复制出现在这里。因此,我们在子列表sublistslet(ready,extend)=子列表(observe(oList(oList oInt))“firstcomponent”(ready++extend),[x]:map(x:) extend)110P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107第一部件[[]、[]] [[]、[]、[3]、[3]][[]、[]、[3]、[3]、[2]、[2,3]、[2,3]]这个观察结果仍然显示了这个bug,但并不能帮助定位它,因为我们无法区分ready和extend的值。一个更好的观察点应该是子列表在递归过程中的结果因此,我们再次修改源代码,并在另一个地方添加一个观察者sublistslet(ready,extend)=observe(oPair(oList(oList oInt))(oList(oListoInt)“(ready++extend,[x]:map(x:)extend)子列表'([[]],[[]])([[],[]],[[3],[3]])([[]、[]、[3]、[3]]、[[2]、[2,3]、[2,3]])在这个观察的第二行中,我们看到bug位于第二个pair组件中。 考虑这个观察,我们看到表达式[x]:map(x:)extend将列表[3]加了两次,因为空列表包含在extend中。 该漏洞位于基础案例中,应更正为:子列表观察数据结构可以帮助发现bug。然而,程序由函数组成,观察COOSY提供的函数更有趣。函数的观测器可以通过右结合运算符来构造:(~>)::观察者a ->观察者b ->观察者(a -> b)在我们的例子中,我们可以使用函数观察器来观察子列表的递归调用sublistslet(ready,extend)=observe(oList oInt~> oPair(oList(oList oInt))(oList(oList oInt)“(ready++extend,[x]:map(x:)extend)子列表'P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107111Fig. 1. 主窗口[]->([[]],[[]])[3]->([[],[]],[[3],[3]])[二、三]->([[],[],[3],[3]],[[2],[2,3],[2,3]])在这种观察中,也有可能检测到bug,在实践中,通过观察函数通常更容易发现bug。然而,在更大的程序中,它仍然是一个添加和删除观察者的迭代,以找到bug的位置,类似于子列表示例的调试会话草图。一个工具,支持程序员在添加和删除观察员是理想的。一个程序iCODE是一个小型的便携式咖喱程序,提供了一个图形界面调试咖喱程序。它使用Curry[6]并将整个程序呈现为一个树,其中包含函数,数据结构和程序的所有定义的子表达式,这些子表达式可能需要观察以发现错误。通过Curry默认情况下,程序(模块)的所有功能都可用。 在选择相应的规则时,用户可以访问函数定义的右侧,并进入表示其所有子表达式的树。另一方面,为了简明扼要,最初的地方定义和112P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107所有子表达式都是隐藏的,并且可以由用户按需打开。 她/他 也可以选择和观察任意的表情。让我们考虑下面的简单程序,它可以实现列表的反向表示:reverse:: [Int]->[Int] reverse []=[]reverse(x:xs)= reverse xs ++[x]函数reverse由两个规则定义,我们将其表示为reverse(1)和reverse(2)。这些规则中的每一个都可以被选择用于观察。 每个规则中的所有表达式都必须在树中呈现。在第一条规则的右边,唯一的表达式是空列表.换句话说,只有表达式[]被呈现给用户。 第二个规则包含三个函数调用:(++)、reverse和(:)。 每个函数接受两个表达式作为参数。此外,每个函数调用本身和所有部分应用程序都被表示出来(参见图1)。现在,通过仅用鼠标单击表达式来选择表达式,iCODE自动将必要的观察功能添加到源代码中,如下节所述,并自动加载更改后的程序在一个新的PAKCS-Shell中,它是为程序员提供的,加入这个项目可以在单独的查看器中自动触发Advance,这些查看器通过它们所属的不同标签进行区分4iCODE中的自动观测在本节中,我们将展示iCODE如何在调试过程中通过自动向选定的表达式和函数添加必要的观察器来4.1观察功能一个方便的观察工具最重要的特点是观察顶级函数。在Curry中,这些函数可以由一个或多个规则定义,并且可以表现为非确定性。观察这样一个函数的想法应该是,对这个函数的每个调用都被观察到。实现此行为的最简单方法在我们第2节的例子中,对所有子列表sublists(oList(oList oInt)哪里“helpSublistslet(ready,extend)=子列表P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107113(ready++extend,[x]:map(x:)extend)注意,我们在包装器函数中重用了原来的函数名。通过保持原始函数定义右侧的递归调用不变,我们保证iCODE观察子列表这种技术也可以应用于局部定义的函数,并由我们的工具提供。4.2观察数据类型使用COOSY(特别是对于初学者)最大的问题是定义新引入的数据类型的观察者,尽管COOSY为这个任务提供了有用的抽象。对于每个用户定义的数据类型,必须定义相应的观察者来观察这种类型的值。我们的工具提供了这些观察者的自动派生,不仅适用于程序中定义的数据类型, 也适用于从其他模块导入的数据类型。我们通过一个例子来概括这个概念。考虑自然数的数据类型数据Nat=O|SNat它定义了两个构造函数, 构造函数O::Nat 的arity为0 ,构造函数S::Nat -> Nat的arity为1。每个类型τ的观察者(例如,Int)应可用作函数oτ(例如, oInt)。因此,我们定义一个观察者。COOSY已经提供了通用的观察者o1,o2,o3,.。. . 观察者oNat可以很容易地定义如下:oNat::ObserverNat oNatO= o0“O” OoNat(S x)= o1 oNat“S”S x对于多态数据类型,观察者也需要多态参数的观察者,如oList。从下面的例子中可以清楚地看出这个结构:数据树a b =分支a b [树a b][树a b]oTree:: Observer x1 -> Observer x2 -> Observer(Tree x1x2)oTree oa ob(Branch x1 x2 x3 x4)=o4 oa ob(oList(oTree oa ob))(oList(oTree oa ob))“分支”分支x1 x2 x3 x4通过这种方式,程序中定义的所有数据结构的通用观察器被自动生成并添加到程序中。这些观察器用于观察函数和表达式对这种类型的值的影响。此方法应用于导入的数据类型,以便为所有导入的模块生成数据类型观察器并自动导入到程序中然而,多态性带来了一个问题。如何观察多态该函数可以用于不同类型的实例化。因此,我们唯一可以分配给它的多态参数的类型是oOpaque。114P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)1074.3观察表达式有时候,观察程序中定义的函数是不够的。观察规则右侧的子表达式对于发现bug是必要用户还可以从函数定义的右侧选择(子)表达式。为此,iCODE提供了整个程序的树表示,用户可以在其中选择要观察的程序的任意(子)表达式相应的observe调用会自动添加,如第2节所示。推断每个所选表达式的类型并生成相应的观察者。iCODE还自动为观察者生成标签,这有助于程序员以后识别观察结果。顶级函数仅用其名称标记。局部函数用冒号分隔的函数名列表标记,导致被观察函数的声明。最后,表达式被标记为相应的函数名和所选表达式的String4.4观察导入的模块iCODE支持将观测添加到项目的不同模块。 当用户选择要观察的模块的函数或表达式时,将生成包含观察者调用的新模块。由于在(即使是间接)导入的模块中也必须执行观察者调用,iCODE可以检查每个导入的模块是否有观察者版本,并使用此版本执行。5iCODE设计随着现代计算机技术的发展,分布式程序设计越来越流行.我们使用客户机/服务器架构,而不是在许多地方存储大量冗余的数据,通常,我们有许多客户机连接到许多服务器。对于Curry中客户端和服务器之间的通信,可以使用TCP通信。在本节中,我们简要回顾iCODE的客户端/服务器架构,以在单独的查看工具中显示观察步骤。5.1架构最初在COOSY中,每次计算取得进展时,有关观测值的信息都作为事件记录在单独的跟踪文件中。有两种事件可以将未计算的表达式与失败或未终止的计算区分开来:需求和值。 需求事件表明需要某个值for the computation计算.值事件表明值的计算已经成功[2]。 这些事件在查看器中显示为文本可视化 酷的。相反,在iCODE中,我们使用Socket在工具的主窗口和所观察的应用程序(PAKCS-System)之间建立连接。的所有事件P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107115观察到的应用程序被发送到iCODE的主窗口。 每个事件都包含其所属观测的标签。使用这种架构,我们还可以图二、连接观察应用程序和主窗口的套接字以单步模式呈现观察结果,帮助初学者理解计算的求值顺序。 通过在此模式下按下前进按钮,在计算继续之前,用户可以延迟客户端以获得来自服务器的确认消息,并且下一个消息被发送到服务器(参见图2)。服务器中接收到的消息被转发到跟踪窗口,用于显示特殊标签的所有观察结果。启动时,每个跟踪窗口都生成一个套接字,并等待从主窗口接收事件,参见图3。图3.第三章。连接主窗口和跟踪窗口的套接字在第2节中,我们已经看到,对于每个观察到的函数/表达式,需要一个标签来匹配观察到的值和观察到的表达式。这些标签将每个观察到的表达式的执行进度分组在单独的跟踪窗口中。这些窗口中的每一个都以相应的标签命名,通过套接字从主窗口接收消息现在,通过发送事件,观察到的值在相关的跟踪窗口中以文本可视化的方式显示给程序员。程序员可以方便地在她/他的屏幕上安排这些窗口,甚至她/他不再感兴趣的近距离观察。5.2观察结果最初在COOSY中,关于观察到的表达式的信息被记录为跟踪文件中的事件列表,该文件被认为是在程序执行后显示这意味着程序员只能在执行终止时观察所选表达式的求值。我们在新版本(iCODE)中的目标是能够显示评估的中间步骤,并可以向前和向后步进。为此,我们使用TCP通信,并将列表数据结构更改为存储在116P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107动态谓词[5]。动态谓词类似于外部函数,其代码不包含在程序中,而是动态计算/扩展的,就像Prolog中的Meta谓词assert和retract在COOSY中,跟踪文件中包含的每个观测标签的观测生成以自下而上的方式工作。 对于观测数据项的连续更新,该算法是没有用的,因为在每一步中,整个观测数据结构必须被重新构造。我们需要一个自上而下的算法,它允许在所有可能的叶位置的数据结构的扩展。例如,在计算过程中,未求值的参数(由undercore表示)可能会转换为值,但数据结构中的值将不再改变。然而,我们必须考虑Curry中的非确定性,通过这种非确定性,值以后可能与不同的非确定性计算有关。我们新的事件表示存储在以下动态谓词中:TreesTable:: [([Index],EvalTree)] -> DynamicTreesTable = dynamicdata EvalTree = Open Int| 值Arity字符串索引[EvalTree]| 需求ArgNr索引[EvalTree]| 趣味指数[EvalTree]| LogVar索引[EvalTree]typeIndex=InttypeArgNr=Inttype Arity= Int动态谓词TreesTable是一种在整个程序中可访问和可修改的全局状态。索引表示相对于它们被添加的顺序出现在相应的评估树(EvalTree)中的所有节点。这是必要的,因为评估顺序不是静态固定的。在第5节中,我们已经看到事件是通过套接字连接从iCODE的主窗口发送到每个跟踪窗口的。每个事件都包含一个逻辑父事件,显示值的构造顺序因此,在一个非确定性分支中,每当扩展评估树时,索引列表[Index]都会在其头部位置扩展,通常是在Open leaf中。如果一个值的一部分被用在多个非确定性计算中,那么逻辑父代指示在两个非确定性计算中共享计算树的哪一部分。我们只考虑由索引列表中的节点组成的子树这个子树和相应的索引被作为一个额外的评估树复制到全局TreesTable中。作为一个例子,我们考虑以下执行非确定性计算的简单程序:P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107117add::Int->Int->Intadd x y = x + ymain = add(0?(1)1表达式(0?1)要么产生0要么产生1。这意味着函数main会产生两个不同的结果0+1和1+1。对于选择要观察的函数add后的第一个结果,将从观察应用程序向主窗口发送十个事件。第一个事件是存储在上面定义的动态树中的需求,索引为0,如下所示:[([0],需求0 0 [(打开1)])]第二个接收到的消息是一个Fun事件,其逻辑父级为0,在父树的开子树中替换[([1,0],需求0 0 [乐趣1 [(打开1),(打开2)]])]这个Fun事件存储为一个节点,其中有两个子树,分别表示参数和相应函数的结果函数以curried形式表示即一个函数的值为2的结果也是函数。在将剩余的八个事件添加到评估树之后,我们获得[([9,8,7,6,5,4,3,2,1,0],需求0)]|Fun1// \需求5需求2||价值6乐趣3|//\“0”需求7需求4||价值观8价值观9||“1”“1”其向用户显示为{\01->1}。下一个传入事件是具有逻辑父事件5的值事件。 此索引不出现在索引列表的头部位置。因此,我们检测到一个非确定性计算.这个计算的观察值与第一棵树共享索引为0到5因此,我们复制这一部分,并将其扩展为new事件10,这意味着同一个函数被另一个参数调用(1)在这个非确定性分支中。在添加三个事件后,我们得到([13,12,11,10,5,4,3,2,1,0],需求0)|Fun1// \需求5需求2118P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107||价值10乐趣3|//\“1”需求11需求4||价值观12价值观13||“1”“2”其向用户示出为{\11->2}。这种方法可以帮助我们为每个中间步骤提供快速漂亮的打印跟踪窗口中的观察结果。 此外,我们可以提供共享部分在第二个演示文稿中使用较浅的颜色显示评估树,这有助于来理解非确定性计算。 图4显示了最后四个步骤的例子。下划线表示未求值的表达式,感叹号表示初始化但未结束的计算。见图4。 跟踪窗口通过将传入事件的数量存储在列表中,我们还可以通过相对于所考虑的索引的子集来过滤TreesTable,从而在一个观察窗口中呈现的观察中执行向后和向前步进。为了从TreesTable中删除评估树,我们定义了一个明确的-按钮在每个跟踪窗口。此外,当观察到的程序重新启动时,TreesTable会自动清除。6程序的执行部分在某些情况下,程序员更喜欢遵循程序执行的顺序,而不是通过观察函数来查看程序在执行过程中的行为。此外,知道程序的哪些部分已经执行对程序员来说是一个有趣的观察者应该只添加到已执行的代码中。iCODE提供了这样一个功能,它也可以用于测试程序的小的独立功能,并专注于程序的小环境进行观察。另一个不断显示程序执行部分的好特性是P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107119如果程序没有更多的解决方案,最后标记的表达式通常会显示计算最终失败的地方。在许多情况下,最后标记的表达式确定意外程序失败或运行时错误的原因。为了保持我们工具的结果视图较小(参见图5),我们以下面的人工程序为例:test:: [Int]->[Int]testxs = bug xs ++ okay xsbug::[Int]->[Int] bug[] =[]okay::[Int] -> [Int]okayxs =xs函数错误代表了一个失败的计算,在实际应用中可能要复杂得多。iCODE对test[1]执行的表示如图5所示。程序再次被表示为树(第3节),其中执行的部分被标记为绿色,最后执行的表达式被标记为红色。我们可以看到函数okay从未被应用。bug可能位于bug到xs的应用程序中,也可能位于函数bug中。此外,我们可以看到,当函数bug应用于xs时,程序最终失败了。图五、标记程序的执行部分查看器还显示了调用已执行函数的次数。 为一个非终止计算,这个信息可以帮助找到非终止递归。对于标记表达式,iCODE会添加对函数markLineNumber的应用于curry程序的查询树中的实际表达式的位置markLineNumber:: String ->Int-> a -> a为了将导入模块的表达式与主模块区分开来,该函数将实际模块的名称作为其第一个参数。第二个参数是实际表达式在表示整个程序的查询树中的位置,第三个参数是函数120P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107markLineNumber的行为与上的标识函数类似。执行此函数时,第一个和第二个参数将作为消息从执行的应用程序发送到iCODE的主窗口(第5节)。在主窗口过程中,消息启动在查看器中实际表达的对应位置的标记,具有在标记的表达上向后和向前步进的能力。这种技术是[3]中定义的程序切片的轻量级实现。此外,研究如何使用这种切片来改进调试将是有趣的,就像[4]中所做的那样7相关工作iCODE是函数逻辑语言Curry的观测调试器,它扩展了Gill它是对COOSY的改进,涵盖了现代函数逻辑语言的所有方面,如惰性计算,高阶函数,非确定性搜索,逻辑变量,并发和约束。iCODE o提供了一个舒适的图形用户界面,帮助用户方便地自动观察任意程序表达式的求值。 它基于漂亮的打印方式,以综合摘要的形式显示观察步骤.HOOD(GHOOD)[7]的图形可视化也使用了Gill的思想来观察程序的表达式。与作为文本可视化的HOOD综合摘要相比,GHOOD基于树形布局算法来实现图形可视化,该算法将程序的所选表达式的结构显示为树。 但是,在GHOOD中也必须手动添加观察员,仍然意味着比使用iCODE更简单为了有一个合适的大型程序的概述,GHOOD提供了一个图形化的可视化而不是文本信息。这是一个很好的教育目的。然而,对于实际应用程序,文本表示似乎更合适,我们决定在iCODE中保留COOSY的文本表示。作为一种改进,我们提出了一个单独的窗口,用户可以方便地移动,甚至关闭在他的图形环境中的每个选定的表达式的跟踪。与调试惰性语言相关的还有Haskell跟踪程序Hat [8]。它以跟踪程序执行的全过程为基础,结合不同的查看工具,支持用户方便地分析记录的轨迹。虽然Hat是一个强大的调试工具,但与基于观察的调试相比,Hat也有一些缺点:• Hat仅限于Haskell的一个子集。Haskell的扩展不容易覆盖,并且Hat根本不能用于分析使用此类扩展的程序• 在执行过程中,会生成大型跟踪文件,这可能会使使用跟踪程序调试实际应用程序的速度变慢。这些缺点并不适用于iCODE,它仍然是轻量级的,并且独立于Curry扩展工作(至少对于程序中不使用P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107121扩展)。 另一方面,将整个程序作为数据结构在iCODE中,可以计算一些更全局的信息(如第6节中讨论的行信息)。然而,iCODE应该是一个轻量级和易于使用的调试器。8结论有时很难弄清楚是什么导致了意外的输出或程序失败。需要一个良好实现的,易于使用的调试器来帮助程序员快速轻松地找到程序中错误的位置我们在新版本中扩展了Curry Object Observation System [2],以提供一个舒适的图形界面作为交互式Curry Observation Debug- ger。它帮助程序员观察她/他的程序的任意表达式的数据结构或函数,以发现错误。使用iCODE非常简单,初学者应该可以使用,我们希望在下一节关于声明式编程的讲座中研究这一点。分布式编程帮助我们通过套接字发送关于所观察到的表达式的信息,并在跟踪窗口中并行显示每个计算出的表达式。跟踪窗口将所选表达式的观察步骤的显示分开,并为程序员提供可理解的结果。在每个跟踪窗口中收集有关观察到的表达式/函数的信息,并为程序员提供了在收集的信息上前进和后退的能力。程序员不需要向她/他的程序添加注释来观察所需的表达式。这些注释由iCODE自动添加。 为程序员提供了一个包含所有程序表达式(即全局和局部函数、模式、变量和所有子表达式)的树。此树中的每个选择都会激活iCODE,自动将注释写入额外的文件中,而无需更改原始程序。还支持由不同模块组成的大型项目。对于未来的工作,我们希望通过为观察到的多态函数的每次使用生成专门的版本来改进多态函数的观察。此外,我们计划研究如何将我们的工具用作Curry的其他开发工具的平台,如重构,测试环境和程序分析。另一个可能的未来工作可能是由于我们的工具保存了大量关于调试程序的Meta信息。因此,可以自动地将观察添加到每个/多个程序函数,并且导出关于不同观察之间的连接的信息,这可以改善调试。引用[1] A.吉尔通过观察中间数据结构来学习Haskell。电子笔记理论Comput. Sci. ,41(1),2000.122P.H. Sadeghi,F.Huch/Electronic Notes in Theoretical Computer Science 177(2007)107[2] B.布拉塞尔岛Chitil,M. Hanus和F. 哈。 观察功能逻辑计算。 第六届声明性语言实践问题国际研讨会论文集(PADLSpringer LNCS 3057,2004年。[3] C. Ochoa , J. Silva 和 G. 维 达 尔 通 过 动 态 切 片 实 现 轻 量 级 程 序 专 业 化 。In Proc. ofCurry andFunctional Logic Programming(WCFLP 2005),第1-7页。ACM Press,2005.[4] O.奇蒂尔基于源的跟踪勘探。In C. Grelck,F. Huch,G. J. Michaelson和P. Trinder,编辑,函数式语言的实现和应用,第16届国际研讨会,IFL 2004,LNCS 3474,第126Springer,2005年3月[5] M.哈纳斯函数逻辑程序中的动态谓词。在函数和逻辑编程杂志,第5卷。EAPLS,2004年。[6] M.Hanus et. PAKCS:波特兰亚琛基尔咖喱系统,2004年。 提供http://www.informatik.uni-kiel.de/~pakcs.[7] C. Reinke. GHOOD -Haskell 天 体 观 测 的 图 形 化 可 视 化 和 动 画 。 Ralf Hinze , 编 辑 , ACM SIGPLANHaskell Workshop,Firenze,Italy,第59卷,Electronic Notes in Theoretical Computer Science,第29页。Elsevier Science,2001年9月。初步会议记录作为技术报告UU-CS-2001-23发表,乌得勒支大学信息和计算科学研究所。在ENTCS进行最后诉讼[8] M. Wallace,O. Chitil,T. Bambum和C.朗西曼Haskell的多视图跟踪:一顶新帽子。在Ralf Hinze,编辑,2001年ACM SIGPLAN Haskell研讨会初步会议记录,第151170页,意大利佛罗伦萨,2001年9月。乌得勒支大学UU-CS-2001-23。最后程序见ENTCS 59(2)。[9] M. 哈纳斯Curry:An Integrated Functional Logic Language,2006.[10] M.哈纳斯图形用户界面的函数逻辑程序设计方法。PADL史普林格出版社[11] J. K. 奥斯特豪特Tcl和Tk Toolkit。Addison Wesley Longman,Inc.1998年
下载后可阅读完整内容,剩余1页未读,立即下载
cpongm
- 粉丝: 5
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 十种常见电感线圈电感量计算公式详解
- 军用车辆:CAN总线的集成与优势
- CAN总线在汽车智能换档系统中的作用与实现
- CAN总线数据超载问题及解决策略
- 汽车车身系统CAN总线设计与应用
- SAP企业需求深度剖析:财务会计与供应链的关键流程与改进策略
- CAN总线在发动机电控系统中的通信设计实践
- Spring与iBATIS整合:快速开发与比较分析
- CAN总线驱动的整车管理系统硬件设计详解
- CAN总线通讯智能节点设计与实现
- DSP实现电动汽车CAN总线通讯技术
- CAN协议网关设计:自动位速率检测与互连
- Xcode免证书调试iPad程序开发指南
- 分布式数据库查询优化算法探讨
- Win7安装VC++6.0完全指南:解决兼容性与Office冲突
- MFC实现学生信息管理系统:登录与数据库操作
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功