You are on page 1of 82

!record Z:\DiscreteStructures\history.txt !record Z:\DiscreteStructures\history.txt !record Z:\DiscreteStructures\history.txt !i Z:\DiscreteStructures\myfuncs.txt !record Z:\DiscreteStructures\history.txt !i Z:\DiscreteStructures\myfuncs.txt !record Z:\DiscreteStructures\history.txt !i \\bh-ac-001\eputterm$\DiscreteStructures\myfuncs.txt !record Z:\DiscreteStructures\history.

txt !record !include Z:\DiscreteStructures\myfuncs.txt !record !i Z:\DiscreteStructures\history.txt Is_Function ; Is_Function := func(s); is_set({3}); is_set({3}); ; !i Z:\DiscreteStructures\myfuncs.txt !record !i Z:\DiscreteStructures\myfuncs.txt !record !i Z:\DiscreteStructures\myfuncs.txt !record !i Z:\DiscreteStructures\myfuncs.txt !record !i Z:\DiscreteStructures\myfuncs.txt !record !include Z:\DiscreteStrucutes\myfuncs.txt !include Z:\DiscreteStructures\myfuncs.txt !record !record !record $ Eli Putterman $ Assignment 1 Is_Smap := func(sm); return is_relation(sm) and #domain(sm) = #sm; end; Is_Perm := func(p); return Is_List(p) and #p = #{x: x in p}; end; Is_Bag := func(b); return Is_Smap(b) and (forall a in image(b) | is_integer(a) and a > 0) end; Is_Relation := func(r,a,b); return is_relation(r) and is_set(a) and is_set(b) and (domain(r) subset a) a nd (image(r) subset b); end; SmapToFunc := func(sm); if Is_Smap(sm) then Func := func(y); return sm(y); end;

return Func; end; end; $ Assignment 2 Is_Pset := func(ps); return is_set(ps) and (forall x in ps | is_set(x) and x /= {}) and (forall x,y in ps | x = y or x inter y = {}); end; Is_Emap := func(em); return is_relation(em) and (forall x,y in domain(em) | ([x,y] in em) = ([y,x ] in em)) and (forall x,y,z in domain(em) | (([x,y] in em) and ([y,z] in em)) = ([x, z] in em)); end; $ Assignment 3 EmapToPset := func(em); if Is_Emap(em) then return {em{x}: x in domain(em)}; end; end; PsetToSmap := func(ps); if Is_Pset(ps) then i := 1; sm := {}; for x in ps do sm := sm + {[y,i] : y in x}; i := i + 1; end; return sm; end; end; $ Assignment 4 Factorial := func(n); if is_integer(n) then if n < 0 then return 0; elseif n = 0 then return 1; else return %*{1..n}; end; end; end; NumLists := func(N,k); if is_integer(N) and is_integer(K) then return n**k; end; end; NumPerms := func(N,k); if is_integer(N) and is_integer(k) then

return Factorial(N) div Factorial(N-k); end; end; NumSets := func(N,k); if is_integer(N) and is_integer(k) then return Factorial(N) div (Factorial(N-k)*Factorial(k)); end; end; NumBags := func(N,k); return NumSets(N+k-1,N-1); end; AllLists := func(S,k); if is_integer(k) and k >= 0 then if k=0 then return {[]}; elseif S = {} then return {}; else return {p with x: x in S, p in AllLists(S,k-1)}; end; end; end; AllSets := func(S,k); if is_integer(k) and k >= 0 then if k=0 then return {{}}; elseif S = {} then return {}; else return {p with x: x in S, p in AllSets(S less x,k-1)}; end; end; end; AllPerms := func(S, k); $ requires: S is a set; k is a nonnegative integer $ effects : returns the set of all perms of S of size k if is_integer(k) and k >= 0 then if k = 0 then return {[]}; elseif S = {} then return {}; elseif k > 0 then return {p with x: x in S, p in AllPerms(S less x,k-1)}; end; end; end; AllBags := func(S,k); if is_integer(k) and k >= 0 then if k=0 then return {{}}; elseif S = {} then return {}; else return {p with [x,1]: x in S, p in AllBags(S less x, k-1)}

+ {p less [x, i] with [x,i+1]: x in S, p in AllBags(S,k-1), [x,i] in p}; end; end; end; AllBagsL := func(S,k); local BagAdd, x; BagAdd := func(p,x); p(x) := 1+p(x)?0; return p; end; if k=0 then return [{}]; elseif S = {} then return []; else x := arb(S); return [BagAdd(p,x): p in AllBagsL(S,k-1)] + [p: p in AllBagsL(S less x,k)]; end; end; $ Assignment 5 !include bin_tree.utl $ bin_tree.utl MakeBinTree := func(left,rootLabel,right); $ requires: left and right are (labeled) binary trees $ effects : returns a new (labeled) binary tree return [left,rootLabel,right]; end; MakeEmpty := func(); $ requires: nothing $ effects : returns an empty binary tree return []; end; IsEmpty := func(tree); $ requires: nothing $ effects : returns true if tree is an empty binary tree and false otherwise return tree = MakeEmpty(); end; MakeBinLeaf := func(item); $ effects : returns a binary tree leaf return MakeBinTree(MakeEmpty(),item,MakeEmpty()); end; IsBinLeaf := func(t); return IsEmpty(Left(t)) and IsEmpty(Right(t)); end; BinRoot := func(t); $ requires: t is a binary tree $ effects : returns the label of root of the tree if is_list(t) then

return t(2); end; end; Left := func(t); $ requires: t is a binary tree $ effects : returns the left subtree of t if is_list(t) then return t(1); end; end; Right := func(t); $ requires: t is a binary tree $ effects : returns the right subtree of t if is_list(t) then return t(3); end; end;

PrintExpTree := proc(t); $ requires: t is a binary expression tree $ effects : prints t RecPrint := proc (level, t ); $ requires: level is a non negative integer; t is a binary tree $ modifies: output stream $ effects : prints the tree at level of indentation if IsBinLeaf(t) then printf BinRoot(t):0, "\n"; else printf BinRoot(t):0; if not IsEmpty(Right(t)) then printf "--->" ; RecPrint(level + 1, Right(t)); end; if not IsEmpty(Left(t)) then for j in [ 1.. 3 ] do for i in [1..level] do printf "| " ; end; if j = 3 then printf "V " ; else printf "| " ; end; printf "\n"; end; for i in [1..level] do printf "| " ; end; RecPrint(level, Left(t)); end; end; end;$ RecPrint printf "\n"; RecPrint(0,t); printf "\n"; end;$ PrintTree;

L2 := MakeBinLeaf(2); L3 := MakeBinLeaf(3); L5 := MakeBinLeaf(5); T23 := MakeBinTree(L2,"+",L3); T53 := MakeBinTree(L5,"-",L3); T := MakeBinTree(T23,"*",T53); Lw := MakeBinLeaf("w"); Lx := MakeBinLeaf("x"); Ly := MakeBinLeaf("y"); Lz := MakeBinLeaf("z"); La := MakeBinLeaf("a"); Lb := MakeBinLeaf("b"); Lc := MakeBinLeaf("c"); Ld := MakeBinLeaf("d"); Le := MakeBinLeaf("e"); Lf := MakeBinLeaf("f"); $ i) Txpy := MakeBinTree(Lx,"+",Ly); Txpz := MakeBinTree(Lx,"+",Lz); T1 := MakeBinTree(Txpy,"*",Txpz); $ ii) Txmy := MakeBinTree(Lx,"-",Ly); Tymw := MakeBinTree(Ly,"-",Lw); Txyz := MakeBinTree(Txmy,"*",Lz); Twxz := MakeBinTree(Txyz,"+",Tymw); T2 := MakeBinTree(Twxz,"*",Lx); $ iii) Taxx := MakeBinTree(La,"*",Lx); Taxb := MakeBinTree(Taxx,"+",Lb); Tabx := MakeBinTree(Taxb,"*",Lx); Taxc := MakeBinTree(Tabx,"+",Lc); Tacx := MakeBinTree(Tacx,"*",Lx); Taxd := MakeBinTree(Tabx,"+",Ld); Tadx := MakeBinTree(Tabc,"*",Lx); Taxe := MakeBinTree(Tabx,"+",Le); Taex := MakeBinTree(Tabd,"*",Lx); T3 := MakeBinTree(Tabx,"+",Lf); Is_Bintree := func(bt); if bt = OM then return false; else return IsEmpty(bt) or (Is_Bintree(Left(bt)) and BinRoot(bt) /= OM and Is_Bintree(Rig ht(bt))); end; end; BinPreorder := func(bt); if Is_Bintree(bt) then if IsEmpty(bt) then return []; else return [BinRoot(bt)]+BinPreorder(Left(bt))+BinPreorder(Right(bt)); end; end; end;

BinInorder := func(bt); if Is_Bintree(bt) then if IsEmpty(bt) then return []; else return BinInorder(Left(bt))+[BinRoot(bt)]+BinInorder(Right(bt)); end; end; end; BinPostorder := func(bt); if Is_Bintree(bt) then if IsEmpty(bt) then return []; else return BinPostorder(Left(bt))+BinPostorder(Right(bt))+[BinRoot(bt)]; end; end; end; Height := func(bt); if Is_Bintree(bt) then if IsEmpty(bt) then return -1; else return 1 + max(Height(Left(bt)),Height(Right(bt))); end; end; end; SameShape := func(at,bt); if Is_Bintree(at) and Is_Bintree(bt) then if IsEmpty(at) then return IsEmpty(bt); else return SameShape(Left(at),Left(bt)) and SameShape(Right(at),Right(bt )); end; end; end; MakeShape := func(bt); if Is_Bintree(bt) then if IsEmpty(bt) then return 0; else return 2**(2**Height(bt)-1) + MakeShape(Left(bt)) + 2**(2**Height(bt ))*MakeShape(Right(bt)); end; end; end; $ utility functions for MakeShape PrintBin := proc(i); if is_integer(i) and i > 0 then if i = 1 then printf "1"; else PrintBin(i div 2);

if i mod 2 = 0 then printf "0"; else printf "1"; end; end; end; end; StringBin := func(i); if is_integer(i) and i > 0 then if i = 1 then return "1"; else if i mod 2 = 0 then return StringBin(i div 2) + "0"; else return StringBin(i div 2) + "1"; end; end; end; end; IntBin := func(i); if is_integer(i) and i > 0 then if i = 1 then return i; else return (10*PrintBin(i div 2)+(i mod 2)); end; end; end; $ Assignment 6 !include ord_tree.utl $ ord_tree.utl 4-28-02 MakeOrdTree := func(root,subtrees); $ requires: root is not OM and subtrees is a list of ordered trees $ effects : returns a new ordered tree with the given root return {["root",root], ["subtrees", subtrees]}; end; MakeNull := func(); return []; end; MakeOrdLeaf := func(item); $ requires: item is not OM $ effects : returns an ordered tree leaf node return MakeOrdTree(item, MakeNull() ); end; Is_OrdLeaf := func(t); $ requires: nothing $ effects : returns true if t is a leaf of an ordered tree and false otherwise return t = MakeOrdLeaf(OrdRoot(t)); end; revised

OrdRoot := func(tree); $ requires: tree is an ordered tree $ effects : returns the root of the tree if Is_Smap(tree) then return tree("root"); end; end; Subtrees := func(tree); $ requires: tree is an ordered tree $ effects : returns the subtrees of the root oftree if Is_Smap(tree) then return tree("subtrees"); end; end; Is_OrdTree := func(t); $ requires: nothing $ effects : returns true if t is an ordered tree and false otherwise return Is_OrdLeaf(t) or (is_defined(OrdRoot(t)) and forall st in Subtrees(t) | Is_OrdTree(st)); end; IsNull := func(forest); $ requires: nothing $ effects : returns true iff forest is empty return forest = MakeNull(); end; HasRoot := func(tree); return is_defined(OrdRoot(tree)); end; PrintOrd := proc(otree); $ requires: otree is an ordered tree or forest of ordered trees $ effects : prints it local printer; printer := func(tr,indent); if HasRoot(tr) then printf indent*" ";print OrdRoot(tr); for t in Subtrees(tr) do printer(t,indent+1); end; else for t in tr do printer(t,indent+1); end; end; end;$ printer printer(otree,1); end; V8 V9 V4 V2 V15 V14 := := := := := := MakeOrdLeaf(8); MakeOrdLeaf(9); MakeOrdTree(4,[V8,V9]); MakeOrdTree(2,[V4]); MakeOrdLeaf(15); MakeOrdTree(14,[V15]);

V13 V10 V5 V6 V11 V12 V7 V3 V1

:= := := := := := := := :=

MakeOrdLeaf(13); MakeOrdTree(10,[V13,V14]); MakeOrdTree(5,[V10]); MakeOrdLeaf(6); MakeOrdLeaf(11); MakeOrdLeaf(12); MakeOrdTree(7,[V11,V12]); MakeOrdTree(3,[V5,V6,V7]); MakeOrdTree(1,[V2,V3]);

AllIntNodes := func(ot); if Is_OrdTree(ot) then if IsNull(ot) then return {}; elseif Is_OrdLeaf(ot) then return {OrdRoot(ot)}; else return {OrdRoot(ot)} + (%+{AllIntNodes(x): x in Subtrees(ot)}); end; end; end; AllLeaves := func(ot); if Is_OrdTree(ot) then if IsNull(ot) then return {}; elseif Is_OrdLeaf(ot) then return {OrdRoot(ot)}; else return %+{AllLeaves(x): x in Subtrees(ot)}; end; end; end; AllNodes := func(ot); if Is_OrdTree(ot) then if IsNull(ot) then return {}; elseif Is_OrdLeaf(ot) then return {OrdRoot(ot)}; else return {OrdRoot(ot)}+(%+{AllNodes(x): x in Subtrees(ot)}); end; end; end; FindSubtree := func(ot,v); if Is_OrdTree(ot) then if OrdRoot(ot) = v then return ot; else for x in Subtrees(ot) do if FindSubtree(x,v) /= OM then return FindSubtree(x,v); end; end; end; end; end;

Parent := func(ot,v); if FindSubtree(ot,v) /= OM then if (exists x in Subtrees(ot) | OrdRoot(x) = v) then return ot; else for x in Subtrees(ot) do if Parent(x,v) /= OM then return Parent(x,v); end; end; end; end; end; Siblings := func(ot,v); if Subtrees(Parent(ot,v)) /= OM then return [x: x in Subtrees(Parent(ot,v)) | OrdRoot(x) /= v]; end; end; Position := func(l,v); $ A utility function returning the position(s) of an item in a list. $ Here used for LeftSiblings and RightSiblings. if v in l then return [x: x in [1..#l] | l(x) = v]; end; end; LeftSiblings := func(ot,v); if Subtrees(Parent(ot,v)) /= OM then S := Subtrees(Parent(ot,v)); return [x: x in S | Position(S,x)(1) < Position(S,FindSubtree(v))(1)]; end; end; LeftSiblings := func(ot,v); if Subtrees(Parent(ot,v)) /= OM then S := Subtrees(Parent(ot,v)); return [x: x in S | Position(S,x)(1) > Position(S,FindSubtree(v))(1)]; end; end; OrdHeight := func(ot); if Is_OrdTree(ot) then if Is_Null(ot) then return -1; else return 1 + %max[OrdHeight(x): x in Subtrees(ot)]; end; end; end; Ancestors := func(ot,v); if Is_OrdTree(ot) and FindSubtree(ot,v) /= OM then if OrdRoot(ot) = v then return []; else return Ancestors(ot,OrdRoot(Parent(ot,v))) + [OrdRoot(Parent(ot,v))] ; end;

end; end; Descendants := func(ot,v); if Is_OrdTree(ot) and FindSubtree(ot,v) /= OM then return [x: x in (AllNodes(ot) - OrdRoot(ot)) | v in Ancestors(ot,x)]; end; end; OrdDepth := func(ot,v); if Is_OrdTree(ot) and FindSubtree(ot,v) /= OM then if v = OrdRoot(ot) then return 0; else return 1 + OrdDepth(Parent(ot,v)); end; end; end; LongestPath := func(ot,v); return %max[OrdDepth(ot,OrdRoot(x)): x in AllLeaves(ot)]; end; Is_Forest := func(f); return is_list(f) and forall x in f | Is_OrdTree(x); end; OrdPreorder := func(ot); if Is_OrdTree(ot) then if IsNull(ot) then return []; elseif Is_OrdLeaf(ot) then return [OrdRoot(ot)]; else return [OrdRoot(ot)] + %+[OrdPreorder(x): x in Subtrees(ot)]; end; end; end; OrdPostorder := func(ot); if Is_OrdTree(ot) then if IsNull(ot) then return []; elseif Is_OrdLeaf(ot) then return [OrdRoot(ot)]; else return %+[OrdPostorder(x): x in Subtrees(ot)] + [OrdRoot(ot)]; end; end; end; ForestToBinTree := func(f); if Is_Forest(f) then if #f = 0 then return MakeEmpty(); else return MakeBinTree( end;

ForestToBinTree(Subtrees(Head(f))), OrdRoot(Head(f)), ForestToBinTree(Tail(f) ) );

end; end; $ Define OrdPreorder(forest) to be %+[OrdPreorder(x): x in forest]. Then: $ BinPreorder(ForestToBinTree(forest)) = OrdPreorder(forest); $ BinInorder(ForestToBinTree(forest)) = OrdPostOrder(forest); $ BinPostorder(ForestToBinTree(forest)), however, does not seem to have any rela tionship $ to a particular ordering of forest. Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and (edge(1) in nodes) and (edge(2) in nodes); end; Is_UndirectedEdge:= func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and (forall a in edge | a in nodes); end; Is_DirectedGraph := func(nodes,edges); return is_set(nodes) and Is_Relation(edges,nodes,nodes); end; Is_UndirectedGraph := func(nodes,edges); return is_set(nodes) and is_set(edges) and (forall edge in edges | Is_Undire ctedEdge(nodes,edge)); end;!include F:\ALebow\ISETLW\isetl.stl completed !stack off !verbose on !memory 30000000 !allocate 30000000 !include funcs.ini !source off !echo off $ standard isetl has domain and image for maps -- and hi,lo for tuples $ here we extend the definitions to more types !unlock domain image hi lo [domain,image,hi,lo] := [Domain,Image,Hi,Lo] where sysdomain := domain; sysimage := image; syslo := lo; syshi := hi; Domain := func(f); if is_tuple(f) then return {i : i in [syslo(f)..syshi(f)]| f(i) /= om}; elseif is_string(f) then return {1..#f}; else return sysdomain(f); end; end; Image := func(f); if is_map(f) then return sysimage(f); else

return { f(x): x in Domain(f) }; end; end; Hi := func(f); return %max Domain(f); end; Lo := func(f); return %min Domain(f); end; end; $ fix and floor are the same on positive numbers and differ on negative ones. $ we may need round, so here it is. round := func(x); if is_number(x) then if x - floor(x) < 1/2 then return floor(x); else return floor(x) + 1; end; end; end; is_list := is_tuple; is_relation := is_map; range := image; !lock image lo hi domain round is_list is_relation range $ !unlock domain $$ leave unlocked to assign domain of funcs !source on $!include message $!i graphs.!i $!include merge.!i !include alias.ini !echo on !alias q quit !alias c clear !alias i include !alias r record !alias w watch !alias uw unwatch !echo off !i list_ops.utl $printf("\tBy including this file 'list_ops.utl' you will be able to use the fu ncs\n"); $printf("\twhose names and parameters are shown below. As far as possible they\n "); $printf("\timplement the descriptions that are found in the Aho & Ullman textboo k,\n"); $printf("\tFoundations of Computer Science. In most cases the names of the \n") ; $printf("\tparameters indicate the required type of argument to be used when \n" ); $printf("\tevaluating the func.\n"); $!echo on

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

Is_List := func(L); Head := func(list); Tail := func(list); Sublist := func( i, j, list); Prefix := func( i,list,); Suffix := func( i, list); First := func(list); Last := func(list); Retrieve := func(position,list); Length := func(list); Is_EmptyList := func(L); Insert := func(item, list); Delete := func(item, list); Lookup := func(item, list); InsertFirst := func(item, list); InsertLast := func(item, list); DeleteFirst := func(item, list); DeleteLast := func(item, list);

$!echo off Is_List := func(L); return is_tuple(L) and (lo(L) = 1 or L=1@[]) and forall x in L | is_defined(x); end; Head := func(list); return list(1); end; Tail := func(list); return list(2..); end; Sublist := func( i, j, list); return list(i..j); end; Prefix := func(i,list); return list(..i); end; Suffix := func(i, list); return list(i..); end; First := func(list); return list(1); end; Last := func(list); return list(#list); end; Retrieve := func(position,list); return list(position); end; Length := func(list); return #list; end; Is_EmptyList := func(L); return L = [] ; end; Insert := func(item, list); local pos; $ position pos := 1 + arb(#list - 1); list(pos..pos) := list(pos..pos) with item;

return list; end; Delete := func(item, list); for p in {1..#list} do if list(p) = item then list(p..p) := []; return list; end; end; return list; end; Lookup := func(item, list); return item in list; end; InsertFirst := func(item, list); return [item] + list; end; InsertLast := func(item, list); return list with item; end; DeleteFirst := func(item, list); for p in [1..#list] do if list(p) = item then list(p..p) := []; return list; end; end; return list; end; DeleteLast := func(item, list); for p in [#list, #list-1..1] do if list(p) = item then list(p..p) := []; return list; end; end; return list; end; Subsequence := func(positions, L); $ requires: positions is a set of positive integers and L is a list $ effects : returns the subsequence of the list L deterimined by positio ns return [L(i): i in [1..#L] | i in positions]; end;

$!i compose.utl $!i relation.!i $!i prob.utl $!i rand.utl $!i arbs.!i $ $printf "Include the file for the course you are taking:\n\n"; $printf "!i disc $ Discrete Structures\n\n"; $printf "!i alg $ Modern Algebra\n\n"; $printf "!i calc $ Calculus\n\n";

printf "\n\n"; printf "Type !record at end of session to close the history.txt file"; printf "\n\n"; !record Z:\history.txt Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and ({x: x in edge} sub set nodes); end; Is_UndirectedEdge:= func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(nodes) and Is_Relation(edges,nodes,nodes); end; Is_UndirectedGraph := func(nodes,edges); return is_set(nodes) and is_set(edges) and (forall edge in edges | Is_Undire ctedEdge(nodes,edge)); end; $ Define OrdPreorder(forest) to be %+[OrdPreorder(x): x in forest]. Then: $ BinPreorder(ForestToBinTree(forest)) = OrdPreorder(forest); $ BinInorder(ForestToBinTree(forest)) = OrdPostOrder(forest); $ BinPostorder(ForestToBinTree(forest)), however, does not seem to have any rela tionship $ to a particular ordering of forest. $ Assignment 7 !record Z:\DiscreteStructures\history.txt !i Z:\DiscreteStructures\myfuncs.txt !record Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and ({x: x in edge} sub set nodes); end; Is_UndirectedEdge:= func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(nodes) and Is_Relation(edges,nodes,nodes); end; Is_UndirectedGraph := func(nodes,edges); return is_set(nodes) and is_set(edges) and (forall edge in edges | Is_Undire ctedEdge(nodes,edge)); end; !record Z:\DiscreteStructures\history.txt OrdPreorder := func(ot); if Is_OrdTree(ot) then if IsNull(ot) then return []; elseif Is_OrdLeaf(ot) then return [OrdRoot(ot)]; else return [OrdRoot(ot)] + %+[OrdPreorder(x): x in Subtrees(ot)]; end; end; end;

OrdPostorder := func(ot); if Is_OrdTree(ot) then if IsNull(ot) then return []; elseif Is_OrdLeaf(ot) then return [OrdRoot(ot)]; else return %+[OrdPostorder(x): x in Subtrees(ot)] + [OrdRoot(ot)]; end; end; end; ForestToBinTree := func(f); if Is_Forest(f) then if #f = 0 then return MakeEmpty(); else return MakeBinTree( end; end; end; $ Define OrdPreorder(forest) to be %+[OrdPreorder(x): x in forest]. Then: $ BinPreorder(ForestToBinTree(forest)) = OrdPreorder(forest); $ BinInorder(ForestToBinTree(forest)) = OrdPostOrder(forest); $ BinPostorder(ForestToBinTree(forest)), however, does not seem to have any rela tionship $ to a particular ordering of forest. $ Assignment 7 Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and ({x: x in edge} sub set nodes); end; Is_UndirectedEdge:= func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(nodes) and Is_Relation(edges,nodes,nodes); end; Is_UndirectedGraph := func(nodes,edges); return is_set(nodes) and is_set(edges) and (forall edge in edges | Is_Undire ctedEdge(nodes,edge)); end; !record Z:\DiscreteStructures\history.txt !include Z:\DiscreteStructures\myfuncs.txt !record !include Z:\DiscreteStructures\myfuncs.txt !record /= a !clear a /= a; a \= a;

ForestToBinTree(Subtrees(Head(f))), OrdRoot(Head(f)), ForestToBinTree(Tail(f) ) );

Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {edge(1), edge(2)} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(edge); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {n : [node,n] in edges}; while (A /= B) do B := A; !clear DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd : [node,nd] in edges}; while (A /= B) do B := A; A := A + {n: nd in A, [nd,n] in edges}; end; end; end; !ids UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: {node,nd} in edges}; !clear while (A /= B) do B := A; A := A + {n: nd in A, {nd,n} in edges}; !clear end; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges}; while (A /= B) do B := A; A := A + {n: nd in A | {nd,n} in edges}; end; end; end; !pp DirectedReach nodes := {'a','b','c','d','e'}; !clear DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd : [node,nd] in edges}; while (A /= B) do B := A; A := A + {n: nd in A, [nd,n] in edges}; end; end;

end; !pp UndirectedReach UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges}; while (A /= B) do B := A; A := A + {n: nd in A | {nd,n} in edges}; end; end; end; !pp UndirectedReach nodes := {'a','b','c','d','e'}; edges := {[b,a],[b,c],[c,b],[d,e],[e,b],[e,c]}; DirectedReach(nodes,edges,'a'); Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge); end; DirectedReach(nodes,edges,'a'); edges = {{a,b}: [a,b] in edges}; edges := {{a,b}: [a,b] in edges}; false; edges := {{a,b}: [a,b] in edges}; edges := {{b,a},{b,c},{c,b},{d,e},{e,b},{e,c}}; UndirectedReach(nodes,edges,'a'); edges := {{'b','a'},{'b','c'},{'c','b'},{'d','e'},{'e','b'},{'e','c'}}; UndirectedReach(nodes,edges,'a'); Is_UndirectedGraph(nodes,edges); 'a' in nodes; !pp UndirectedReach UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges}; while (A /= B) do B := A; A := A + {n: nd in A | {nd,n} in edges}; end; end; return A; end; UndirectedReach(nodes,edges,'a'); !pp DirectedReach DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: [node,nd] in edges}; while (A /= B) do B := A; A := A + {n: nd in A, [nd,n] in edges}; end; end; return A; end; edges := {['b','a'],['b','c'],['c','b'],['d','e'],['e','b'],['e','c']}; DirectedReach(nodes,edges,'a'); "a"; 'a'; {n: ['a',n] in edges};

!clear {n: n in nodes | ['a',n] in edges}; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges}; while (A /= B) do B := A; A := A + {n: nd in A | [nd,n] in edges}; end; end; return A; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges}; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; end; return A; end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges}; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; end; return A; end; DirectedReach(nodes,edges,'a'); DirectedReach(nodes,edges,'b'); edges' edges; !clear edges; DirectedReach(nodes,edges,'d'); edges; edges := {{"e", "c"}, {"e", "b"}, {"d", "e"}, {"b", "c"}, {"b", "a"}, {"c", "b"} }; UndirectedReach(nodes,edges,'b'); UndirectedReach(nodes,edges,'a'); UndirectedReach(nodes,edges,'c'); UndirectedReach(nodes,edges,'d'); UndirectedReach(nodes,edges,'e'); Connected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return UndirectedReach(nodes,edges,arb(nodes)) = nodes; elseif if Is_DirectedGraph(nodes,edges) then return DirectedReach(nodes,edges,arb(nodes)) = nodes; else return false; end; !clear end; !clear StronglyConnected := func(nodes,edges); if Is_DirectedGraph(nodes,edges) then return UndirectedReach(nodes,edges,arb(nodes)) = nodes;

elseif if Is_DirectedGraph(nodes,edges) then return DirectedReach(nodes,edges,arb(nodes)) = nodes; elseif if Is_DirectedGraph(nodes,edges) then return DirectedReach(nodes,edges,arb(nodes)) = nodes; else return false; end; !clear StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return UndirectedReach(nodes,edges,arb(nodes)) = nodes; elseif if Is_DirectedGraph(nodes,edges) then return DirectedReach(nodes,edges,arb(nodes)) = nodes; else return false; end; !clear StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return UndirectedReach(nodes,edges,arb(nodes)) = nodes; elseif if Is_DirectedGraph(nodes,edges) then return DirectedReach(nodes,edges,arb(nodes)) = nodes; else return false; end; !clear StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return UndirectedReach(nodes,edges,arb(nodes)) = nodes; elseif Is_DirectedGraph(nodes,edges) then return DirectedReach(nodes,edges,arb(nodes)) = nodes; else return false; end; end; StronglyConnected(nodes,edges); edges; !pp DirectedReach DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; end; return A; end; !pp UndirectedReach UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; end; return A; end; Is_RootedTree := func(nodes,edges); and StronglyConnected(nodes,edges) and #edges = #nodes - 1; !clear

Is_RootedTree := func(nodes,edges); return Is_UndirectedGraph(nodes,edges) and StronglyConnected(nodes,edges) and #edges = #nodes - 1; end; !pp StronglyConnected StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; !clear SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; edges; Dedges := {["e", "d"], ["c", "e"], ['e','c'], ["e", "b"], ["b", "a"], ["b", "c"] }; SimplyConnected(nodes,Dedges); Is_RootedTree(nodes,Dedges); StronglyConnected(nodes,edges); StronglyConnected(nodes,Dedges); !i Z:\DiscreteStructures\myfuncs.txt !record !i Z:\DiscreteStructures\myfuncs.txt !record !i Z:\DiscreteStructures\myfuncs.txt !record Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subset n odes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge); end; !pp Z:\DiscreteStructures\myfuncs.txt Is_DirectedEdge !pp Is_DirectedEdge Z:\DiscreteStructures\myfuncs.txt !pp Is_UndirectedEdge !pp Is_DirectedGraph !pp Is_UndirectedGraph DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A;

A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end ; !pp DirectedReach !pp !pp DirectedReach UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; !pp UndirectedReach Z:\DiscreteStructures\myfuncs.txt StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; !pp StronglyConnected SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(no des,edges,node) = nodes; end; !pp SimplyConnected Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PossibleRoots := func(nodes,edges); if Is_RootedTree(nodes,edges) then; !clear PossibleRoots := func(nodes,edges); if Is_RootedTree(nodes,edges) then return {n: n in nodes | DirectedReach(nodes,edges,node) = nodes}; end; end; !pp Is_RootedTree !pp PossibleRoots Parent := func(nodes,edges); if Is_RootedTree(nodes,edges) then return {[b,a]: [a,b] in edges}; end; end; nodes := {'a','b','c','d','e'}; edges := {['d edges := {['d','e'],['e','b'],['e','c'],['b','a']}; !clear edges := {['d','e'],['e','b'],['e','c'],['b','a']}; Parent(nodes,edges); Parent('d');

Parent(nodes,edges)("d"); Parent(nodes,edges)("e"); PathFromRoot := func(nodes,edges); if Is_RootedTree(nodes,edges) then PathFromRoot := func(node,parent); !clear PathFromRoot := func(node,parent); $ requires: node in domain(parent) and $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way $ requires: node in domain(parent) and l = [node]; while(parent(par) /= OM) par := parent(node); !clear PathFromRoot := func(node,parent); $ requires: node in domain(parent) and $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way $ requires: node in domain(parent) and $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way $ requires: node in domain(parent) and l := [node]; while(parent(par) /= OM) par := parent(node); !clear PathFromRoot := func(node,parent); $ requires: node in domain(parent) and $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way $ requires: node in domain(parent) and $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way $ requires: node in domain(parent) and l := [node]; par := parent(node); while(par /= OM) l := [par] + l; !clear PathFromRoot := func(node,parent); $ requires: node in domain(parent) and $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way $ requires: node in domain(parent) and $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way $ requires: node in domain(parent) and path := [node]; par := parent(node); while(par /= OM) do path := [par] + path; par := parent(par);

parent is the

parent is the

parent is the

parent is the

parent is the

parent is the

parent is the

parent is the

parent is the

parent is the

parent is the

end; return path; end; PathFromRoot('a',Parent(nodes,edges)); edges; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way $ requires: node in domain(parent) and parent is the path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; PathFromRoot('a',Parent(nodes,edges)); !pp PathFromRoot min; max; lo; !pp lo !pp !pp lo lo; !ids !locker !locked MakeCounter := func(); local count; count := 0; return func(); count := count + 1; return count; end; end; a := MakeCounter(); a; a(); a(); a(); MakeCounter := func(); local count; count := 0; counter := func(); count := count + 1; return count; end; return counter; end; a := MakeCounter(); a(); a(); a(); MakeCounter := func(); count := 0; counter := func(); count := count + 1;

return count; end; return counter; end; a := MakeCounter(); a(); a(); a(); b := MakeCounter(); b(); b(); a(); a(); b(); MakeCounter := func(); local count; count := 0; counter := func(); count := count + 1; return count; end; return counter; end; b := MakeCounter(); a(); 1; a(); 2; a(); 3; b := MakeCounter(); b(); 1; b(); 2; a(); !i Z:\DiscreteStructures\myfuncs.txt !record Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node);

if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set

$ $

2) in the fringe and adjacent to a node in marked 3) can be reached from a node in the fringe marked := {}; fringe := {root}; $ loop while fringe /= {} do take node from fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked then fringe := fringe with v; end; end; end; return marked;

end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); !clear !i Z:\DiscreteStructures\myfuncs.txt !record !i Z:\DiscreteStructures\myfuncs.txt !record Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end;

UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := {root}; $ loop while fringe /= {} do take node from fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked then

fringe := fringe with v; end; end; end; return marked; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end;

end; end; !clear !record !i Z:\DiscreteStructures\myfuncs.txt !record !i Z:\DiscreteStructures\myfuncs.txt !record !i Z:\DiscreteStructures\myfuncs.txt !record Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge );

end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, node;

$ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := {root}; $ loop while fringe /= {} do take node from fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked then fringe := fringe with v; end; end; end; return marked; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; $ you fill in the code for... fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs> Is_DirectedEdge := func(nodes,edge); !ids !pp ReachTree ! allocate 50000000 ! allocate 40000000 ! allocate 35000000 ! allocate 30000000 ! allocate 12 !memory 50000000 !memory 500000000 !i Z:\DiscreteStructures\myfuncs.txt

!record Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end;

PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := {root}; edges := {}; $ loop while fringe /= {} do take node from fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end;

return func(state); local fillNbrs, emptyNbrs, pourNbrs; $ you fill in the code for... fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs> Is_DirectedEdge := func(nodes,edge); Buckets := [5,3,3]; bgraph := MkBucketNbrs(Buckets); bgraph; ReachTree([0,0,0],bgraph); #ReachTree([0,0,0],bgraph); btree := ReachTree([0,0,0],bgraph); bnodes := domain(btree) + range(btree); IsRootedTree(bnodes,btree); Is_RootedTree(bnodes,btree); Buckets := [4,2]; bgraph := MkBucketNbrs(Buckets); btree := ReachTree([0,0,0],bgraph); > btree := ReachTree([0,0],bgraph); !clear btree := ReachTree([0,0],bgraph); bnodes := domain(btree) + range(btree); Is_RootedTree(bnodes,btree); bnodes; btree; #btree; bgraph; !pp bgraph bgraph([0,0]); bgraph([3,0]); ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := {root}; edges := {}; $ loop while fringe /= {} do take node from fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; btree := ReachTree([0,0],MakeBucketNbrs); btree := ReachTree([0,0],MakeBucketNbrs(Buckets));

*** btree := ReachTree([0,0],MkBucketNbrs(Buckets)); !clear btree := ReachTree([0,0],MakeBucketNbrs(Buckets)); *** btree := ReachTree([0,0],MakeBucketNbrs); !clear btree := ReachTree([0,0],MkBucketNbrs(Buckets)); bnodes := domain(btree); Is_RootedTree(bnodes,btree); bnodes; bnodes := domain(btree) + range(btree); Is_RootedTree(bnodes,btree); bnodes; btree; #btree; #bnodes; !pp Is_RootedTree SimplyConnected(bnodes,btree); !pp SimplyConnected btree := {[a,b]: [b,a] in btree}; btree; Is_RootedTree(bnodes,btree); b := {[a,b]: [b,a] in {2}}; *** b := {[a,b]: [b,a] in {[2,3]}}; !clear b := {[a,b]: [b,a] in {[2,3]}}; b; b := {[a,b]: [b,a] in {[2,3],5}}; [a,b] := [3,4]; a; b; #SolveBucketProblem([3,7,5,6],[0,0,0,0],[0,3,1,2]); SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; #SolveBucketProblem([3,7,5,6],[0,0,0,0],[0,3,1,2]); MkBucketNbrs([0,0,0,0]); SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; #SolveBucketProblem([3,7,5,6],[0,0,0,0],[0,3,1,2]); SolveBucketProblem([3,7,5,6],[0,0,0,0],[0,3,1,2]); SolveBucketProblem([3,7,5,6],[0,7,2,2],[0,3,1,2]); SolveBucketProblem([4,7,4,4],[0,7,2,2],[0,3,1,2]); SolveBucketProblem([4,7,4,4],[0,0,0,0],[2,5,2,2]); SolveBucketProblem([4,7,4,4],[0,0,0,0],[3,5,2,2]); OM;

SolveBucketProblem([4,7,4,4],[0,0,0,0],[3,5,1,2]); SolveBucketProblem([4,7,4,4],[0,0,0,0],[3,5,1,4]); SolveBucketProblem([4,6,5,4],[0,0,0,0],[3,5,1,4]); SolveBucketProblem([5,7,5,5],[0,0,0,0],[4,4,4,4]); SolveBucketProblem([5,7,5,5],[0,0,0,0],[4,4,3,4]); SolveBucketProblem([5,7,5,5],[0,0,0,0],[3,4,3,4]); SolveBucketProblem([5,7,5,5],[0,0,0,0],[3,4,3,3]); ReachTree(start,MkBucketNbrs(capBucket)); ReachTree(start,MkBucketNbrs(capBucket)); ReachTree([0,0,0,0],MkBucketNbrs([5,7,5,5])); tree := ReachTree([0,0,0,0],MkBucketNbrs([5,7,5,5])); leaves := {x: x in domain(tree) | x notin range(tree)}; leaves; #leaves; #tree; leaves := {PathFromRoot(x,tree): x in domain(tree) | x notin range(tree)}; leaves; l := {x: x in leaves | #x > 20}; l; l := {x: x in leaves | #x > 30}; l; #l(1); #arb(l); #arb(l); forall x in l | #x = 31; #l; choose x in leaves | x(#x) = [1,7,1,1]; Reachable := func(root,Neighbors,NewHolder); $ requires: Neighbors(node) returns the set of nodes adjacent to node $ NewHolder returns an empty holder-object $ effects : returns the set of nodes that can be reached from root local marked, fringe, node; marked := {}; !clear !pp SolveBucketNumbers !pp SolveBucketProblem ReachTreeQ := func(root,Neighbors,NewHolder); $ requires: Neighbors(node) returns the set of nodes adjacent to node $ NewHolder returns an empty holder-object $ effects : returns the set of nodes that can be reached from root local marked, edges, fringe, node; marked := {}; !clear ReachTreeQ := func(root,Neighbors,NewHolder); $ requires: Neighbors(node) returns the set of nodes adjacent to node $ NewHolder returns an empty holder-object $ effects : returns the set of nodes that can be reached from root local marked, edges, fringe, node; marked := {}; fringe := NewHolder(); edges := {}; Put(root,fringe); $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) already in the marked set $ 2) at most one edge away from a marked node and in the fringe

3) can be reached from nodes in the fringe $ loop while not IsEmptyH(fringe) do node := Take(fringe); marked := marked with node; for v in Neighbors(node) do if v notin marked then Put(v,fringe); edges := edges with [v,node]; end; end; end; return marked;

end; SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTreeQ(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; tree := ReachTreeQ([0,0,0,0],MkBucketNbrs([5,7,5,5])); tree := ReachTreeQ([0,0,0,0],MkBucketNbrs([5,7,5,5]), NewQueue); !pp NewQueue NewQueue := func(); local queue, Enqueue, Dequeue, IsEmptyH; queue := []; Enqueue := proc(x); queue := queue with x; end; Pop := func(); local x; take x fromb queue; return x; end; IsEmptyH := func(); return queue = []; end; return {["put",Push],["take",Dequeue],["empty?",IsEmptyH]}; end; $ Any holder-object can be used with these interface funcs. Put := proc(item,holder); $ requires: item is not OM, holder responds to "put" $ modifies: holder $ effects : puts item into holder holder("put")(item); end; Take := func(holder); $ requires: holder is not empty $ modifies: holder $ effects : removes an item from holder and returns the item return holder("take")(); end;

IsEmptyH := func(holder); $ requires: $ modifies: nothing $ effects : return holder("empty?")(); end;> NewQueue := func(); !clear tree := ReachTreeQ([0,0,0,0],MkBucketNbrs([5,7,5,5]), NewQueue); NewQueue()("put"); !i Z:\DiscreteStructures\ReachObj.txt $ File : Reach&Obj.txt ReachTreeQ := func(root,Neighbors,NewHolder); $ requires: Neighbors(node) returns the set of nodes adjacent to node $ NewHolder returns an empty holder-object $ effects : returns the set of nodes that can be reached from root local marked, edges, fringe, node; marked := {}; fringe := NewHolder(); edges := {}; Put(root,fringe); $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) already in the marked set $ 2) at most one edge away from a marked node and in the fringe $ 3) can be reached from nodes in the fringe $ loop while not IsEmptyH(fringe) do node := Take(fringe); marked := marked with node; for v in Neighbors(node) do if v notin marked then Put(v,fringe); edges := edges with [v,node]; end; end; end; return marked; end; $ Here is a holder object. You should write funcs for other $ holder-objects, Queue, Mutable sets NewStack := func(); $ requires: nothing $ effects : returns a new empty stack-object local stack, Push, Pop, IsEmptyH; stack := []; Push := proc(x); stack := [x] + stack; $ puts x at top of stack end; Pop := func(); local x; take x fromb stack; $ takes x from top of stack return x; end; IsEmptyH := func();

return stack = []; end; return {["put",Push],["take",Pop],["empty?",IsEmptyH]}; end; NewQueue := func(); local queue, Enqueue, Dequeue, IsEmptyH; queue := []; Enqueue := proc(x); queue := queue with x; end; Pop := func(); local x; take x fromb queue; return x; end; IsEmptyH := func(); return queue = []; end; return {["put",Push],["take",Dequeue],["empty?",IsEmptyH]}; end; $ Any holder-object can be used with these interface funcs. Put := proc(item,holder); $ requires: item is not OM, holder responds to "put" $ modifies: holder $ effects : puts item into holder holder("put")(item); end; Take := func(holder); $ requires: holder is not empty $ modifies: holder $ effects : removes an item from holder and returns the item return holder("take")(); end; IsEmptyH := func(holder); $ requires: $ modifies: nothing $ effects : return holder("empty?")(); end; tree := ReachTreeQ([0,0,0,0],MkBucketNbrs([5,7,5,5]), NewQueue); !i Z:\DiscreteStructures\ReachObj.txt $ File : Reach&Obj.txt ReachTreeQ := func(root,Neighbors,NewHolder); $ requires: Neighbors(node) returns the set of nodes adjacent to node $ NewHolder returns an empty holder-object $ effects : returns the set of nodes that can be reached from root local marked, edges, fringe, node; marked := {}; fringe := NewHolder(); edges := {}; Put(root,fringe); $ The following is true before each iteration of the $ loop

$ All nodes that can be reached from root are of 3 kinds: $ 1) already in the marked set $ 2) at most one edge away from a marked node and in the fringe $ 3) can be reached from nodes in the fringe $ loop while not IsEmptyH(fringe) do node := Take(fringe); marked := marked with node; for v in Neighbors(node) do if v notin marked then Put(v,fringe); edges := edges with [v,node]; end; end; end; return marked; end; $ Here is a holder object. You should write funcs for other $ holder-objects, Queue, Mutable sets NewStack := func(); $ requires: nothing $ effects : returns a new empty stack-object local stack, Push, Pop, IsEmptyH; stack := []; Push := proc(x); stack := [x] + stack; $ puts x at top of stack end; Pop := func(); local x; take x fromb stack; $ takes x from top of stack return x; end; IsEmptyH := func(); return stack = []; end; return {["put",Push],["take",Pop],["empty?",IsEmptyH]}; end; NewQueue := func(); local queue, Enqueue, Dequeue, IsEmptyH; queue := []; Enqueue := proc(x); queue := queue with x; end; Dequeue := func(); local x; take x fromb queue; return x; end; IsEmptyH := func(); return queue = []; end; return {["put",Enqueue],["take",Dequeue],["empty?",IsEmptyH]}; end; $ Any holder-object can be used with these interface funcs.

Put := proc(item,holder); $ requires: item is not OM, holder responds to "put" $ modifies: holder $ effects : puts item into holder holder("put")(item); end; Take := func(holder); $ requires: holder is not empty $ modifies: holder $ effects : removes an item from holder and returns the item return holder("take")(); end; IsEmptyH := func(holder); $ requires: $ modifies: nothing $ effects : return holder("empty?")(); end; tree := ReachTreeQ([0,0,0,0],MkBucketNbrs([5,7,5,5]), NewQueue); ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; tree := ReachTree([0,0,0,0],MkBucketNbrs([5,7,5,5])); leaves := {x: x in domain(tree) | x notin range(tree)}; paths := {PathFromRoot(x),x in leaves}; paths := {PathFromRoot(x,tree): x in leaves};

paths; p := {x: x in paths | #x > 30}; p; p := {x: x in paths | #x > 20}; p; p := {x: x in paths | #x > 25}; p; > p := {x: x in paths | #x > 23}; !clear p := {x: x in paths | #x > 23}; p; p := {x: x in paths | #x > 22}; p; list := [1,2,3,4]; list(2..2); list(2..2) := [5,5,5]; list; !locked Is_Perm := func(p); return Is_List(p) and #p = #{x: x in p}; end; AllLists := func(S,k); if is_integer(k) and k >= 0 then if k=0 then return {[]}; elseif S = {} then return {}; else return {p with x: x in S, p in AllLists(S,k-1)}; end; end; end; "abc"(1); "abc"(2..3) = "bca"(1..2); SRSeq := func(alph,N); $ modifies: nothing $ effects : returns a string of size (#alph ** N) that $ has all strings of size N with the chars of $ alph as substrings (with wrap-around) local nodes, edges, cycle; if is_string(alph) and Is_Perm(alph) and is_integer(n) and n > 0 then $ test s alph and N nodes := AllLists(alph,N-1); edges := {[n1,n2]: n1, n2 in nodes | n1(2..N-1) = n2(1..N-2)}; cycle := EulerCycle(nodes,edges); return [node(1): node in cycle]; end; end; SRSeq("abc",3); Is_List("abc"); SRSeq := func(alph,N); $ modifies: nothing $ effects : returns a string of size (#alph ** N) that $ has all strings of size N with the chars of $ alph as substrings (with wrap-around) local nodes, edges, cycle; if is_string(alph) and Is_Perm([x: x in alph]) and is_integer(n) and n > 0 t hen $ tests alph and N nodes := AllLists(alph,N-1); edges := {[n1,n2]: n1, n2 in nodes | n1(2..N-1) = n2(1..N-2)};

cycle := EulerCycle(nodes,edges); return %+[node(1): node in cycle]; end; end; SRSeq("abc",3); is_string("abc"); SRSeq := func(alph,N); $ modifies: nothing $ effects : returns a string of size (#alph ** N) that $ has all strings of size N with the chars of $ alph as substrings (with wrap-around) local nodes, edges, cycle; if is_string(alph) and Is_Perm([x: x in alph]) and is_integer(N) and N > 0 t hen $ tests alph and N nodes := AllLists(alph,N-1); edges := {[n1,n2]: n1, n2 in nodes | n1(2..N-1) = n2(1..N-2)}; cycle := EulerCycle(nodes,edges); return %+[node(1): node in cycle]; end; end; SRSeq("abc",3); Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end;

StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; MkBucketNbrs := func(capBucket);

$ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node) return #[l: l in edges | l(2) = node]; !clear end; OutDegree := func(node) return #[l: l in edges | l(1) = node]; end; if StronglyConnected(nodes,edges) then return forall node in nodes | InDegree(node) = OutDegree(node); end; EulerCycle := func(nodes,edges); $ effects : return an Euler cycle of the directed graph GetCycle := func(node); $ requires: node is on one of the graphEdges $ effects : returns a cycle from node and deletes its edges from the

set edges edge := arb([e: e in edges | e(1) = node]); current := edge(2); cycle := [node,current]; local edge, current, cycle; while(current /= node) do edge := arb([e: e in edges | e(1) = current]); current := edge(2); edges := edges less edge; cycle := cycle with current; end; return cycle; end func;$ GetCycle $ begin main func if HasEulerCycle(nodes,edges) then !clear !clear Is_Perm := func(p); return Is_List(p) and #p = #{x: x in p}; end; AllLists := func(S,k); if is_integer(k) and k >= 0 then if k=0 then return {[]}; elseif S = {} then return {}; else return {p with x: x in S, p in AllLists(S,k-1)}; end; end; end; Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A;

end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do

take node fromb fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node) return #[l: l in edges | l(2) = node]; !clear end; OutDegree := func(node)

return #[l: l in edges | l(1) = node]; end; if StronglyConnected(nodes,edges) then return forall node in nodes | InDegree(node) = OutDegree(node); end; EulerCycle := func(nodes,edges); $ effects : return an Euler cycle of the directed graph GetCycle := func(node); $ requires: node is on one of the graphEdges $ effects : returns a cycle from node and deletes its edges from the $ set edges edge := arb([e: e in edges | e(1) = node]); current := edge(2); cycle := [node,current]; local edge, current, cycle; while(current /= node) do edge := arb([e: e in edges | e(1) = current]); current := edge(2); edges := edges less edge; cycle := cycle with current; end; return cycle; end func;$ GetCycle $ begin main func if HasEulerCycle(nodes,edges) then !clear !clear Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end;

end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe;

marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node) return #[l: l in edges | l(2) = node]; !clear end; OutDegree := func(node) return #[l: l in edges | l(1) = node];

end; if StronglyConnected(nodes,edges) then return forall node in nodes | InDegree(node) = OutDegree(node); end; EulerCycle := func(nodes,edges); $ effects : return an Euler cycle of the directed graph GetCycle := func(node); $ requires: node is on one of the graphEdges $ effects : returns a cycle from node and deletes its edges from the $ set edges edge := arb([e: e in edges | e(1) = node]); current := edge(2); cycle := [node,current]; local edge, current, cycle; while(current /= node) do edge := arb([e: e in edges | e(1) = current]); current := edge(2); edges := edges less edge; cycle := cycle with current; end; return cycle; end func;$ GetCycle $ begin main func if HasEulerCycle(nodes,edges) then !clear !clear Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do

B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end;

end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node); return #[l: l in edges | l(2) = node]; end; OutDegree := func(node); return #[l: l in edges | l(1) = node]; end; if StronglyConnected(nodes,edges) then !clear Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs

et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree

$ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]};

emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node); return #[l: l in edges | l(2) = node]; end; OutDegree := func(node); return #[l: l in edges | l(1) = node]; end; if StronglyConnected(nodes,edges) then !clear Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then

A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v;

edges := edges with [v,node]; end; end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node); return #[l: l in edges | l(2) = node]; end; OutDegree := func(node); return #[l: l in edges | l(1) = node]; end; if StronglyConnected(nodes,edges) then !clear

Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent);

$ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state);

local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node); return #[l: l in edges | l(2) = node]; end; OutDegree := func(node); return #[l: l in edges | l(1) = node]; end; if StronglyConnected(nodes,edges) then !clear Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end;

UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe; marked := marked with node; for v in AdjacentNodes(node) do

if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node); return #[l: l in edges | l(2) = node]; end; OutDegree := func(node); return #[l: l in edges | l(1) = node]; end; if StronglyConnected(nodes,edges) then

!clear Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end;

PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state;

end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node); return #[l: l in edges | l(2) = node]; end; OutDegree := func(node); return #[l: l in edges | l(1) = node]; end; if StronglyConnected(nodes,edges) then !clear Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end;

end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe;

marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node]; end; end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node); return #[l: l in edges | l(2) = node]; end; OutDegree := func(node); return #[l: l in edges | l(1) = node]; end;

if StronglyConnected(nodes,edges) then return forall node in nodes | InDegree(node) = OutDegree(node); end; end; EulerCycle := func(nodes,edges); $ effects : return an Euler cycle of the directed graph local GetCycle, cycle; GetCycle := func(node); $ requires: node is on one of the graphEdges $ modifies: edges $ effects : returns a cycle from node and deletes its edges from the $ set edges edge := arb([e: e in edges | e(1) = node]); current := edge(2); cycle := [node,current]; local edge, current, cycle; !clear while(current /= node) do edge := arb([e: e in edges | e(1) = current]); current := edge(2); edges := edges less edge; cycle := cycle with current; end; return cycle; end func;$ GetCycle !clear !clear Is_DirectedEdge := func(nodes,edge); return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subs et nodes; end; Is_UndirectedEdge := func(nodes,edge); return is_set(nodes) and is_set(edge) and #edge = 2 and edge subset nodes; end; Is_DirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_DirectedEdge(nodes,edge); end; Is_UndirectedGraph := func(nodes,edges); return is_set(edges) and forall edge in edges | Is_UndirectedEdge(nodes,edge ); end; DirectedReach := func(nodes,edges,node); if Is_DirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | [node,nd] in edges} with node; while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | [nd,n] in edges}; end; return A; end; end; UndirectedReach := func(nodes,edges,node); if Is_UndirectedGraph(nodes,edges) and node in nodes then A := {nd: nd in nodes | {node,nd} in edges} with node;

while (A /= B) do B := A; A := A + {n: nd in A, n in nodes | {nd,n} in edges}; end; return A; end; end; StronglyConnected := func(nodes,edges); if Is_UndirectedGraph(nodes,edges) then return forall node in nodes | UndirectedReach(nodes,edges,node) = nodes; elseif Is_DirectedGraph(nodes,edges) then return forall node in nodes | DirectedReach(nodes,edges,node) = nodes; else return false; end; end; SimplyConnected := func(nodes,edges); return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes; end; Is_RootedTree := func(nodes,edges); return SimplyConnected(nodes,edges) and #edges = #nodes - 1; end; PathFromRoot := func(node,parent); $ requires: node in domain(parent) and parent is the $ reversed edges of a rooted tree $ effects : returns a path from root to node $ in an efficient way path := []; while(node /= OM) do path := [node] + path; node := parent(node); end; return path; end; ReachTree := func(root,AdjacentNodes); $ requires: AdjacentNodes(x) returns the set of nodes adjacent to x $ effects : returns the set of nodes that can be reached from root local marked, fringe, edges, node; $ The following is true before each iteration of the $ loop $ All nodes that can be reached from root are of 3 kinds: $ 1) in the marked set $ 2) in the fringe and adjacent to a node in marked $ 3) can be reached from a node in the fringe marked := {}; fringe := [root]; edges := {}; $ loop while fringe /= [] do take node fromb fringe; marked := marked with node; for v in AdjacentNodes(node) do if v notin marked and v notin domain(edges) then fringe := fringe with v; edges := edges with [v,node];

end; end; end; return edges; end; MkBucketNbrs := func(capBucket); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem $ effects : returns the func for the neighbors of a node $ in the graph of the buckets and well problem local Fill, Empty, Pour; Fill := func(state,i); state(i) := capBucket(i); return state; end; Empty := func(state,i); state(i) := 0; return state; end; Pour := func(state,i,j); local amount; $ the amout to be poured from bucket i to bucket j amount := min(capBucket(j)-state(j),state(i)); state(i) := state(i) - amount; state(j) := state(j) + amount; return state; end; return func(state); local fillNbrs, emptyNbrs, pourNbrs; fillNbrs := {Fill(state,i): i in [1..#state]}; emptyNbrs := {Empty(state,i): i in [1..#state]}; pourNbrs := {Pour(state,i,j): i,j in [1..#state] | i /= j}; return fillNbrs + emptyNbrs + pourNbrs; end func; $ unnamed func end func; $ MkBucketNbrs SolveBucketProblem := func(capBucket,start,solution); $ requires: capBucket is a list of integers = capacities $ of the buckets in a buckets and well problem, $ start is the starting state, and solution is $ the desired ending state. $ effects: returns a path from start to solution tree := ReachTree(start,MkBucketNbrs(capBucket)); if solution notin domain(tree) then return OM; end; return PathFromRoot(solution,tree); end; HasEulerCycle := func(nodes,edges); local InDegree, OutDegree; InDegree := func(node); return #[l: l in edges | l(2) end; OutDegree := func(node); return #[l: l in edges | l(1) end; if StronglyConnected(nodes,edges) return forall node in nodes | end; end;

= node]; = node]; then InDegree(node) = OutDegree(node);

EulerCycle := func(nodes,edges); $ effects : return an Euler cycle of the directed graph local GetCycle, cycle; GetCycle := func(node); $ requires: node is on one of the graphEdges $ modifies: edges $ effects : returns a cycle from node and deletes its edges from the $ set edges local edge, current, cycle; edge := arb([e: e in edges | e(1) = node]); current := edge(2); cycle := [node,current]; while(current /= node) do edge := arb([e: e in edges | e(1) = current]); current := edge(2); edges := edges less edge; cycle := cycle with current; end; return cycle; end func;$ GetCycle if HasEulerCycle(nodes,edges) then cycle := GetCycle(arb(nodes)); while edges /= {} do for i in [1..#cycle] do if cycle(i) in domain(edges) then cycle(i..i) := GetCycle(cycle(i)); end; end; end; return cycle; end; end; SRSeq := func(alph,N); $ modifies: nothing $ effects : returns a string of size (#alph ** N) that $ has all strings of size N with the chars of $ alph as substrings (with wrap-around) local nodes, edges, cycle; if is_string(alph) and Is_Perm(alph) and is_integer(n) and n > 0 then $ test s alph and N nodes := AllLists(alph,N-1); edges := {[n1,n2]: n1, n2 in nodes | n1(2..N-1) = n2(1..N-2)}; cycle := EulerCycle(nodes,edges); return [node(1): node in cycle]; end; end;> Is_DirectedEdge := func(nodes,edge); !clear Is_Perm := func(p); return Is_List(p) and #p = #{x: x in p}; end; AllLists := func(S,k); if is_integer(k) and k >= 0 then if k=0 then return {[]}; elseif S = {} then return {}; else return {p with x: x in S, p in AllLists(S,k-1)}; end;

end; end; SRSeq("abc",3); !pp SRSeq SRSeq := func(alph,N); $ modifies: nothing $ effects : returns a string of size (#alph ** N) that $ has all strings of size N with the chars of $ alph as substrings (with wrap-around) local nodes, edges, cycle; if is_string(alph) and Is_Perm(alph) and is_integer(n) and n > 0 then $ test s alph and N nodes := AllLists(alph,N-1); edges := {[n1,n2]: n1, n2 in nodes | n1(2..N-1) = n2(1..N-2)}; cycle := EulerCycle(nodes,edges); return [node(1): node in cycle]; end; end; SRSeq("abc",3); is_string("abc"); SRSeq := func(alph,N); $ modifies: nothing $ effects : returns a string of size (#alph ** N) that $ has all strings of size N with the chars of $ alph as substrings (with wrap-around) local nodes, edges, cycle; if is_string(alph) and Is_Perm([x: x in alph]) and is_integer(n) and n > 0 t hen $ tests alph and N nodes := AllLists(alph,N-1); edges := {[n1,n2]: n1, n2 in nodes | n1(2..N-1) = n2(1..N-2)}; cycle := EulerCycle(nodes,edges); return [node(1): node in cycle]; end; end; SRSeq("abc",3); SRSeq := func(alph,N); $ modifies: nothing $ effects : returns a string of size (#alph ** N) that $ has all strings of size N with the chars of $ alph as substrings (with wrap-around) local nodes, edges, cycle; if is_string(alph) and Is_Perm([x: x in alph]) and is_integer(N) and N > 0 t hen $ tests alph and N nodes := AllLists(alph,N-1); edges := {[n1,n2]: n1, n2 in nodes | n1(2..N-1) = n2(1..N-2)}; cycle := EulerCycle(nodes,edges); return [node(1): node in cycle]; end; end; SRSeq("abc",3); edge; current; node; EulerCycle := func(nodes,edges); $ effects : return an Euler cycle of the directed graph local GetCycle, cycle; GetCycle := func(node); $ requires: node is on one of the graphEdges $ modifies: edges $ effects : returns a cycle from node and deletes its edges from the

set edges local edge, current, cycle; edge := arb([e: e in edges | e(1) = node]); edges := edges less edge; current := edge(2); cycle := [node,current]; while(current /= node) do edge := arb([e: e in edges | e(1) = current]); current := edge(2); edges := edges less edge; cycle := cycle with current; end; return cycle; end func;$ GetCycle if HasEulerCycle(nodes,edges) then cycle := GetCycle(arb(nodes)); while edges /= {} do for i in [1..#cycle] do if cycle(i) in domain(edges) then cycle(i..i) := GetCycle(cycle(i)); end; end; end; return cycle; end; end;> EulerCycle := func(nodes,edges); !clear EulerCycle := func(nodes,edges); $ effects : return an Euler cycle of the directed graph local GetCycle, cycle; GetCycle := func(node); $ requires: node is on one of the graphEdges $ modifies: edges $ effects : returns a cycle from node and deletes its edges from the $ set edges local edge, current, cycle; edge := arb([e: e in edges | e(1) = node]); edges := edges less edge; current := edge(2); cycle := [node,current]; while(current /= node) do edge := arb([e: e in edges | e(1) = current]); current := edge(2); edges := edges less edge; cycle := cycle with current; end; return cycle; end func;$ GetCycle if HasEulerCycle(nodes,edges) then cycle := GetCycle(arb(nodes)); while edges /= {} do for i in [1..#cycle] do if cycle(i) in domain(edges) then cycle(i..i) := GetCycle(cycle(i)); end; end; end; return cycle; end; end;

SRSeq("abc",3); SRSeq := func(alph,N); $ modifies: nothing $ effects : returns a string of size (#alph ** N) that $ has all strings of size N with the chars of $ alph as substrings (with wrap-around) local nodes, edges, cycle; if is_string(alph) and Is_Perm([x: x in alph]) and is_integer(N) and N > 0 t hen $ tests alph and N nodes := AllLists(alph,N-1); edges := {[n1,n2]: n1, n2 in nodes | n1(2..N-1) = n2(1..N-2)}; cycle := EulerCycle(nodes,edges); return %+[node(1): node in cycle]; end; end; SRSeq("abc",3); SRSeq := func(alph,N); $ modifies: nothing $ effects : returns a string of size (#alph ** N) that $ has all strings of size N with the chars of $ alph as substrings (with wrap-around) local nodes, edges, cycle; if is_string(alph) and Is_Perm([x: x in alph]) and is_integer(N) and N > 0 t hen $ tests alph and N nodes := AllLists(alph,N-1); edges := {[n1,n2]: n1, n2 in nodes | n1(2..N-1) = n2(1..N-2)}; cycle := EulerCycle(nodes,edges); return %+[node(1): node in cycle(1..#cycle-1)]; end; end; SRSeq("abc",3); #SRSeq("abc",3); TestSRString := func(str,n,N); return is_string(str) and #str = n ** N and #{(str+str(1..n-1))(a..a+n-1): a in [1..#str]} = n ** N; end; TestSRString("bbcbbaccbcccacaaacbabcabaab"); TestSRString("bbcbbaccbcccacaaacbabcabaab",3,3); TestSRString("bbcbbaccbcccacaaacbabcabaa",3,3); TestSRString("bbcbbaccbcccacaaacbabcabaac",3,3); TestSRString(SRSeq("cdfi2",4)); TestSRString(SRSeq("cdfi2",4),5,4); SRSeq("cdfi2",4); #("2c2dc2fidcfc2fccd2idfi2idc2cd2fiiiidcdc22fcfccccdcff22f2idi2ciciiicdiccc2ifdf idif2d2cdc" +"iddcifcdi2dffff2fffcifdci2dccci2cfddc2ddd2ii22cccf2fic22iddfc2i22i2fi22d2fc2di 2222iif2" +"ifc2cidfd2ic2f2ccfcd2dfcciidicfdc2icfcfd22iccfdiiifd2fdcfid2d2ifffdcddfiidf2f2 dd2cffid" +"fcdff2c2fddii2diidd222dic2id22dfdcc222ffccfifiddicdcdf2df2iid2ffd2cif22c2c22dd fdfdici2" +"iciffc22cfcid2cc2ffi2ddifci22fdidccididddffdifdi2ificfi2fd2dcfdf222ci2fcii2cci fii2f22i" +"f2fdffiifi2cdfddf2ciicidciifcc2ccdidffcffcddccffdfcicf22dcicc2dfifcf2cdiff2icd 2c2iii2i" +"2d22cdd2f2fcdccdfcfiic2cf2dcd22fifficddddcdiiffdd2dififdddidiicfffif2cficcddi2 ff2did2i" +"2iiccicdficic2d2ddcf2i"); is_string('a'); PreorderToTree := func(pl);

local getTree; getTree := func(); local root, right, left; take root fromb pl; if root notin "+-*/" then return MakeBinLeaf(root); else left := getTree(); right := getTree(); return MakeBinTree(left,root,right); end; end; return getTree(); end; !i bin_tree.utl $ bin_tree.utl MakeBinTree := func(left,rootLabel,right); $ requires: left and right are (labeled) binary trees $ effects : returns a new (labeled) binary tree return [left,rootLabel,right]; end; MakeEmpty := func(); $ requires: nothing $ effects : returns an empty binary tree return []; end; IsEmpty := func(tree); $ requires: nothing $ effects : returns true if tree is an empty binary tree and false otherwise return tree = MakeEmpty(); end; MakeBinLeaf := func(item); $ effects : returns a binary tree leaf return MakeBinTree(MakeEmpty(),item,MakeEmpty()); end; IsBinLeaf := func(t); return IsEmpty(Left(t)) and IsEmpty(Right(t)); end; BinRoot := func(t); $ requires: t is a binary tree $ effects : returns the label of root of the tree if is_list(t) then return t(2); end; end; Left := func(t); $ requires: t is a binary tree $ effects : returns the left subtree of t if is_list(t) then return t(1); end; end;

Right := func(t); $ requires: t is a binary tree $ effects : returns the right subtree of t if is_list(t) then return t(3); end; end;

PrintExpTree := proc(t); $ requires: t is a binary expression tree $ effects : prints t RecPrint := proc (level, t ); $ requires: level is a non negative integer; t is a binary tree $ modifies: output stream $ effects : prints the tree at level of indentation if IsBinLeaf(t) then printf BinRoot(t):0, "\n"; else printf BinRoot(t):0; if not IsEmpty(Right(t)) then printf "--->" ; RecPrint(level + 1, Right(t)); end; if not IsEmpty(Left(t)) then for j in [ 1.. 3 ] do for i in [1..level] do printf "| " ; end; if j = 3 then printf "V " ; else printf "| " ; end; printf "\n"; end; for i in [1..level] do printf "| " ; end; RecPrint(level, Left(t)); end; end; end;$ RecPrint printf "\n"; RecPrint(0,t); printf "\n"; end;$ PrintTree; PrintExpTree(PreorderToTree(["+","-","+",3,5,3,4]); !clear PrintExpTree(PreorderToTree(["+","-","+",3,5,3,4])); PrintExpTree(PreorderToTree(["+","-","+","3","5","3","4"]));NumBST = func(n); if n = 0 then return 1; else return %+[NumBST(k)*NumBST(n-1-k): k in [0..n-1]]; end ; end; !pp NumBST NumBST = func(n); if n = 0 then return 1;

else return %+[NumBST(k)*NumBST(n-1-k): k in [0..n-1]]; end; end; NumBST := func(n); if n = 0 then return 1; else return %+[NumBST(k)*NumBST(n-1-k): k in [0..n-1]]; end; end; NumBST(5); NumBST(28); NumBST(20); NumBST(10); NumBST(15);wordfile = openr("words.txt"); wordfile := openr("words.txt"); list := []; i := 1; while not eof(wordfile) do readf(list(i) from wordfile; !clear Wordread := func(); wordfile := openr("words.txt"); list := []; i := 1; while not eof(wordfile) do readf(list(i) from wordfile; !clear Wordread := func(); wordfile := openr("words.txt"); list := []; i := 1; while not eof(wordfile) do readf list(i) from wordfile; i := i + 1; end; end; Wordread(); Wordread := func(); wordfile := openr("words.txt"); list := []; i := 1; while not eof(wordfile) do readf list(i) from wordfile; i := i + 1; end; return list; end; Wordread(); #["a", "AAA", "AAAS", "Aarhus", "Aaron", "ABA", "Ababa", "aback", "abacus", "aba lone", "abandon", "abase", "abash", ; !clear #["a", "AAA", "AAAS", "Aarhus", "Aaron", "ABA", "Ababa", "aback", "abacus", "aba lone", "abandon", "abase", "abash", ; !clear l := Wordread(); ; !clear l; #l;!include Z:\DiscreteStructures\myfuncs.txt

!record

You might also like