Ошибки в Mozart/Oz с примерами обхода дерева из книги Concepts, Techniques, and Models of Computer Programming

Заранее спасибо и извиняюсь за любые ошибки или что-то непонятное в моем посте.

Я получаю ошибки с примерами обхода дерева в разделе 3.4.6 "Концепции, методы и модели компьютерного программирования". Я использую Oz/mozart2-2.0.0-alpha.0 (+build.4091-slitaz-1.01.ova).

Я ввожу приведенные ниже процедуры и функции точно так же, как они описаны в книге (две версии книги с немного другим кодом), и получаю ошибки при попытке выполнить. Я пытался исправить их самостоятельно, но пока ничего не получается. Ниже я приведу код, операторы выполнения, ошибки и объявление тестового дерева (которое кажется действительным, поскольку я могу без проблем выполнить {LookUp}, {Insert} и {Delete}). Ниже я добавлю дополнительные примечания, если сочту нужным.

Итак, мой вопрос: что не так с этими фрагментами кода или как я их использую или с моими деревьями? Я включил функцию и три процедуры, которые дают одну и ту же проблему для решения (и, возможно, помогают в устранении неполадок), но я думаю, что решение одинаково для всех.

Объявление дерева последнее, ниже.

КОД -->

%All of the below errors occur upon execution, not on definition of the proc or function

% version: VanRoyHaridi2003-book.pdf
% section 3.4.6 - "Trees","Tree Traversal", "Depth-first traversal
% p.159 (Adobe Reader p. 202 of 939)

declare 
proc {DFS T}
   case T
   of leaf then skip
   [] tree(Key Val L R) then
      {DFS L}
      {Browse Key#Val}
      {DFS R}
   end
end

{DFS S}

/*
%******************** Error: conditional failed *****************
%**
%** Missing else clause
%**
%** Matching: tree(key:250 left:tree(key:125 left:tree(key:60 left:tree(key:30 left:leaf right:leaf value:pyramid) right:tree(key:90 left:leaf right:leaf value:cube) value:sphere) right:tree(key:185 left:tree(key:155 left:leaf right:leaf value:wave) right:tree(key:215 left:leaf right:leaf value:plane) value:shadow) value:shape) right:tree(key:375 left:tree(key:315 left:tree(key:285 left:leaf right:leaf value:boing) right:tree(key:345 left:leaf right:leaf value:ring) value:tap) right:tree(key:435 left:tree(key:405 left:leaf right:leaf value:whoosh) right:tree(key:465 left:leaf right:leaf value:ping) value:boom) value:sounds) value:treetop)
%** in file "/mnt/host_folder/trees - traversals", line 39
%**
%** Call Stack:
%** procedure 'DFS' in file "/mnt/host_folder/trees - traversals", line 33, column 1, PC = -1279897415
%**--------------------------------------------------------------
*/

% version: CTMchapters1-3.pdf, "Tree Traversal" p.155 (Adobe Read p. 181 of 226)
% section 3.4.6.2, "Tree Traversal"
declare
proc {DFS T}
   case T
   of leaf then skip
   [] tree(Key Val L R) then
      {Browse Key#Val}
      {DFS L}     
      {DFS R}
   end
end

{DFS S}
% {DFS T} version two had the same error as the 1st version
% I know they are trivially different, but included it anyway... sorry

% Same page as {DFS T} in CTMchapters1-3.pdf (only).
declare
proc {DFSAccLoop T S1 ?Sn}
   case T
   of leaf then Sn=S1
   [] tree(Key Val L R) then S2 S3 in
      S2=Key#Val|S1
      {DFSAccLoop L S2 S3}
      {DFSAccLoop L S3 Sn}
   end
end
fun {DFSAcc T} {Reverse {DFSAccLoop S nil $}} end

{Browse {DFSAcc S}}
/*
%******************** Error: conditional failed *****************
%**
%** Missing else clause
%**
%** Matching: tree(key:250 left:tree(key:125 left:tree(key:60 left:tree(key:30 left:leaf right:leaf value:pyramid) right:tree(key:90 left:leaf right:leaf value:cube) value:sphere) right:tree(key:185 left:tree(key:155 left:leaf right:leaf value:wave) right:tree(key:215 left:leaf right:leaf value:plane) value:shadow) value:shape) right:tree(key:375 left:tree(key:315 left:tree(key:285 left:leaf right:leaf value:boing) right:tree(key:345 left:leaf right:leaf value:ring) value:tap) right:tree(key:435 left:tree(key:405 left:leaf right:leaf value:whoosh) right:tree(key:465 left:leaf right:leaf value:ping) value:boom) value:sounds) value:treetop)
%** in file "/mnt/host_folder/trees - traversals", line 67
%**
%** Call Stack:
%** procedure 'DFSAccLoop' in file "/mnt/host_folder/trees - traversals", line 61, column 1, PC = -1239512161
%** procedure 'DFSAcc' in file "/mnt/host_folder/trees - traversals", line 70, column 1, PC = -1239496575
%** toplevel abstraction in line 1, column 0, PC = -1238883005
%**--------------------------------------------------------------

*/

% One of the versions of {LookUp X T} gives the same error.

% version: CTMchapters1-3.pdf, "Tree Traversal" p.152 (Adobe Read p. 178 of 226)
% section 3.4.6.2, "Storing information in trees"
declare
fun {Lookup X T}
   case T
   of leaf then notfound
   [] tree(Y V T1 T2) then
      if X<Y then {Lookup X T1}
      elseif X>Y then {Lookup X T2}
      else found(V) end
   end
end
/*
%******************** Error: conditional failed *****************
%**
%** Missing else clause
%**
%** Matching: tree(key:horse left:tree(key:dog left:tree(key:cat left:leaf right:leaf value:chat) right:tree(key:elephant left:leaf right:leaf value:elephant) value:chien) right:tree(key:mouse left:tree(key:monkey left:leaf right:leaf value:singe) right:tree(key:tiger left:leaf right:leaf value:tigre) value:souris) value:cheval)
%** in file "/mnt/host_folder/Lookup Insert Delete", line 37
%**
%** Call Stack:
%** procedure 'Lookup' in file "/mnt/host_folder/Lookup Insert Delete", line 31, column 1, PC = -1241765194
%** toplevel abstraction in line 1, column 0, PC = -1241110606
%**--------------------------------------------------------------
*/

% the case version works, so I was suprised when the traversals using case are not working for me.
declare
fun {Lookup K T} 
   case T of leaf then notfound
   [] tree(key:X value:V left:T1 right:T2) andthen X==K then found(V)
   [] tree(key:X value:V left:T1 right:T2) andthen X<K then {Lookup K T2}
   [] tree(key:X value:V left:T1 right:T2) andthen X>K then {Lookup K T1}
   end
end

% There are two test trees here
declare
S=tree(key:250 value:treetop
       left:tree(key:125 value:dash
                 left:tree(key:60 value:sphere
                           left:tree(key:30 value:pyramid left:leaf right:leaf)
                           right:tree(key:90 value:cube left:leaf right:leaf))
                 right:tree(key:185 value:shadow
                            left:tree(key:155 value:wave left:leaf right:leaf)
                            right:tree(key:215 value:plane left:leaf right:leaf)))
       right:tree(key:375 value:hum
                  left:tree(key:315 value:tap
                            left:tree(key:285 value:boing left:leaf right:leaf)
                            right:tree(key:345 value:ring left:leaf right:leaf))
                  right:tree(key:435 value:boom
                             left:tree(key:405 value:whoosh left:leaf right:leaf)
                             right:tree(key:465 value:ping left:leaf right:leaf))))

T=tree(key:horse value:cheval
       left:tree(key:dog value:chien
                 left:tree(key:cat value:chat left:leaf right:leaf)
                 right:tree(key:elephant value:elephant left:leaf right:leaf))
       right:tree(key:mouse value:souris
                  left:tree(key:monkey value:singe left:leaf right:leaf)
                  right:tree(key:tiger value:tigre left:leaf right:leaf)))

{Browse S}
{Browse T}

person crh777    schedule 21.01.2016    source источник


Ответы (2)


Глядя на вашу первую программу: ваше объявление дерева неверно, поскольку вы можете видеть, что компилятор не может сопоставить ваше дерево ни с одним из предложений, определенных в структуре case, например, для первой программы вы пытаетесь сопоставить что-то в этой форме ( упрощенная форма вашей декларации):

S=tree(key:250 value:treetop left:leaf right:leaf)

с этими пунктами:

of leaf then skip
[] tree(Key Val L R)

S не может совпадать ни с leaf, ни со вторым, так как Key не может совпадать с key:250, поэтому компилятор выдает вам эту ошибку. Вы можете объявить свое дерево как:

S = tree(250 treetop tree(120 foo leaf leaf) tree(100 foo2 leaf leaf))

Вы можете исправить теперь в соответствии с этим другие программы.

person rok    schedule 23.01.2016
comment
Большое спасибо. Это действительно кажется проблемой. Мне нужно будет вернуться и посмотреть, почему эти определения работают, например, с функциями/процедурами LookUp, Insert и Delete из той же книги. Вероятно, мне нужно обратить пристальное внимание на определение типа, возможно, оно было изменено для обходов, а я был слишком невнимателен, чтобы заметить. Еще раз большое спасибо, теперь я могу вернуться к изучению того, как работают эти обходы. - person crh777; 23.01.2016
comment
Функции LookUp, Insert, Delete, которые я использовал ранее, включали ключ:, значение: и т. д. в сопоставление с образцом, поэтому они работали со старой версией дерева. Я думаю, что сопоставление с образцом, которое работает на старом дереве, работает, потому что key: и т. д. являются атомами. [] дерево (ключ: значение X: V слева: T1 справа: T2) - person crh777; 23.01.2016

Проблема возникает из-за того, что вы неправильно сопоставляете дерево. Когда вы пишете

fun {Lookup X T}
   case T
   of leaf then notfound
   [] tree(Y V T1 T2) then
      % ...
   end
end

tree(Y V T1 T2) неявно преобразуется в tree(1:Y 2:V 3:T1 4:T2). Это синтаксический сахар, предлагаемый Oz: если вы не укажете признаки при объявлении записи, они будут неявно добавлены для вас как возрастающие целые числа, начиная с 1.

Чтобы правильно сопоставить дерево, вы должны явно указать правильные функции:

fun {Lookup X T}
   case T
   of leaf then notfound
   [] tree(key:Y value:V left:T1 right:T2) then
      % ...
   end
end
person francoisr    schedule 07.03.2016