isetl functions
TRANSCRIPT
-
7/27/2019 ISETL functions
1/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.txtIs_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;
-
7/27/2019 ISETL functions
2/82
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 thenreturn 0;
elseif n = 0 thenreturn 1;
elsereturn %*{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
-
7/27/2019 ISETL functions
3/82
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 thenreturn {[]};
elseif S = {} thenreturn {};
elsereturn {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 thenreturn {{}};
elseif S = {} thenreturn {};
elsereturn {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 thenif 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 thenreturn {{}};
elseif S = {} thenreturn {};
elsereturn {p with [x,1]: x in S, p in AllBags(S less x, k-1)}
-
7/27/2019 ISETL functions
4/82
+ {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
-
7/27/2019 ISETL functions
5/82
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) thenreturn t(1);
end;end;
Right := func(t);$ requires: t is a binary tree$ effects : returns the right subtree of t
if is_list(t) thenreturn t(3);
end;end;
PrintExpTree := proc(t);$ requires: t is a binary expression tree
$ effects : prints tRecPrint := 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) thenprintf BinRoot(t):0, "\n";
elseprintf BinRoot(t):0;if not IsEmpty(Right(t)) then
printf "--->" ;RecPrint(level + 1, Right(t));
end;
if not IsEmpty(Left(t)) thenfor j in [ 1.. 3 ] dofor 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;$ RecPrintprintf "\n";RecPrint(0,t);printf "\n";
end;$ PrintTree;
-
7/27/2019 ISETL functions
6/82
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) thenreturn [];
elsereturn [BinRoot(bt)]+BinPreorder(Left(bt))+BinPreorder(Right(bt));
end;end;
end;
-
7/27/2019 ISETL functions
7/82
BinInorder := func(bt);if Is_Bintree(bt) then
if IsEmpty(bt) thenreturn [];
elsereturn BinInorder(Left(bt))+[BinRoot(bt)]+BinInorder(Right(bt));
end;end;
end;
BinPostorder := func(bt);if Is_Bintree(bt) then
if IsEmpty(bt) thenreturn [];
elsereturn BinPostorder(Left(bt))+BinPostorder(Right(bt))+[BinRoot(bt)];
end;end;
end;
Height := func(bt);if Is_Bintree(bt) then
if IsEmpty(bt) thenreturn -1;
elsereturn 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) thenreturn IsEmpty(bt);
elsereturn 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) thenreturn 0;
elsereturn 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 thenprintf "1";
elsePrintBin(i div 2);
-
7/27/2019 ISETL functions
8/82
if i mod 2 = 0 thenprintf "0";
elseprintf "1";
end;end;
end;end;
StringBin := func(i);if is_integer(i) and i > 0 then
if i = 1 thenreturn "1";
elseif 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 thenif i = 1 thenreturn i;
elsereturn (10*PrintBin(i div 2)+(i mod 2));
end;end;
end;
$ Assignment 6
!include ord_tree.utl$ ord_tree.utl revised
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;
-
7/27/2019 ISETL functions
9/82
OrdRoot := func(tree);$ requires: tree is an ordered tree$ effects : returns the root of the tree
if Is_Smap(tree) thenreturn 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) thenreturn 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 itlocal printer;printer := func(tr,indent);
if HasRoot(tr) thenprintf indent*" ";print OrdRoot(tr);for t in Subtrees(tr) do
printer(t,indent+1);end;
elsefor t in tr do
printer(t,indent+1);end;
end;
end;$ printerprinter(otree,1);
end;
V8 := MakeOrdLeaf(8);V9 := MakeOrdLeaf(9);V4 := MakeOrdTree(4,[V8,V9]);V2 := MakeOrdTree(2,[V4]);V15 := MakeOrdLeaf(15);V14 := MakeOrdTree(14,[V15]);
-
7/27/2019 ISETL functions
10/82
V13 := MakeOrdLeaf(13);V10 := MakeOrdTree(10,[V13,V14]);V5 := MakeOrdTree(5,[V10]);V6 := MakeOrdLeaf(6);V11 := MakeOrdLeaf(11);V12 := MakeOrdLeaf(12);V7 := MakeOrdTree(7,[V11,V12]);V3 := MakeOrdTree(3,[V5,V6,V7]);V1 := MakeOrdTree(1,[V2,V3]);
AllIntNodes := func(ot);if Is_OrdTree(ot) then
if IsNull(ot) thenreturn {};
elseif Is_OrdLeaf(ot) thenreturn {OrdRoot(ot)};
elsereturn {OrdRoot(ot)} + (%+{AllIntNodes(x): x in Subtrees(ot)});
end;end;
end;
AllLeaves := func(ot);if Is_OrdTree(ot) then
if IsNull(ot) thenreturn {};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) thenreturn {OrdRoot(ot)};
elsereturn {OrdRoot(ot)}+(%+{AllNodes(x): x in Subtrees(ot)});
end;end;
end;
FindSubtree := func(ot,v);if Is_OrdTree(ot) then
if OrdRoot(ot) = v thenreturn ot;
elsefor x in Subtrees(ot) do
if FindSubtree(x,v) /= OM thenreturn FindSubtree(x,v);
end;end;
end;end;
end;
-
7/27/2019 ISETL functions
11/82
Parent := func(ot,v);if FindSubtree(ot,v) /= OM then
if (exists x in Subtrees(ot) | OrdRoot(x) = v) thenreturn ot;
elsefor x in Subtrees(ot) do
if Parent(x,v) /= OM thenreturn 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) thenreturn -1;
elsereturn 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 thenreturn [];
elsereturn Ancestors(ot,OrdRoot(Parent(ot,v))) + [OrdRoot(Parent(ot,v))]
;end;
-
7/27/2019 ISETL functions
12/82
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) thenreturn 0;
elsereturn 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) thenreturn [];
elseif Is_OrdLeaf(ot) thenreturn [OrdRoot(ot)];
elsereturn [OrdRoot(ot)] + %+[OrdPreorder(x): x in Subtrees(ot)];
end;end;
end;
OrdPostorder := func(ot);if Is_OrdTree(ot) then
if IsNull(ot) thenreturn [];
elseif Is_OrdLeaf(ot) thenreturn [OrdRoot(ot)];
elsereturn %+[OrdPostorder(x): x in Subtrees(ot)] + [OrdRoot(ot)];
end;end;
end;
ForestToBinTree := func(f);if Is_Forest(f) then
if #f = 0 thenreturn MakeEmpty();
elsereturn MakeBinTree( ForestToBinTree(Subtrees(Head(f))),
OrdRoot(Head(f)),ForestToBinTree(Tail(f) ) );
end;
-
7/27/2019 ISETL functions
13/82
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 relationship$ 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_UndirectedEdge(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) thenreturn {i : i in [syslo(f)..syshi(f)]| f(i) /= om};
elseif is_string(f) thenreturn {1..#f};
elsereturn sysdomain(f);
end;end;Image := func(f);
if is_map(f) thenreturn sysimage(f);
else
-
7/27/2019 ISETL functions
14/82
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 thenreturn floor(x);
elsereturn 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 funcs\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 textbook,\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
-
7/27/2019 ISETL functions
15/82
$ 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;
-
7/27/2019 ISETL functions
16/82
return list;end;Delete := func(item, list);
for p in {1..#list} doif 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] doif 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] doif 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 positions
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";
-
7/27/2019 ISETL functions
17/82
printf "\n\n";printf "Type !record at end of session to close the history.txt file";printf "\n\n";!record Z:\history.txtIs_DirectedEdge := func(nodes,edge);
return is_set(nodes) and is_list(edge) and #edge = 2 and ({x: x in edge} subset 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 relationship$ to a particular ordering of forest.
$ Assignment 7!record Z:\DiscreteStructures\history.txt!i Z:\DiscreteStructures\myfuncs.txt!recordIs_DirectedEdge := func(nodes,edge);
return is_set(nodes) and is_list(edge) and #edge = 2 and ({x: x in edge} subset 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_UndirectedEdge(nodes,edge));end;!record Z:\DiscreteStructures\history.txtOrdPreorder := func(ot);
if Is_OrdTree(ot) then
if IsNull(ot) thenreturn [];
elseif Is_OrdLeaf(ot) thenreturn [OrdRoot(ot)];
elsereturn [OrdRoot(ot)] + %+[OrdPreorder(x): x in Subtrees(ot)];
end;end;
end;
-
7/27/2019 ISETL functions
18/82
OrdPostorder := func(ot);if Is_OrdTree(ot) then
if IsNull(ot) thenreturn [];
elseif Is_OrdLeaf(ot) thenreturn [OrdRoot(ot)];
elsereturn %+[OrdPostorder(x): x in Subtrees(ot)] + [OrdRoot(ot)];
end;end;
end;
ForestToBinTree := func(f);if Is_Forest(f) then
if #f = 0 thenreturn MakeEmpty();
elsereturn MakeBinTree( ForestToBinTree(Subtrees(Head(f))),
OrdRoot(Head(f)),ForestToBinTree(Tail(f) ) );
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 relationship$ 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!cleara /= a;a \= a;
-
7/27/2019 ISETL functions
19/82
Is_DirectedEdge := func(nodes,edge);return is_set(nodes) and is_list(edge) and #edge = 2 and {edge(1), edge(2)} subset 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 thenA := {n : [node,n] in edges};while (A /= B) doB := A;!clearDirectedReach := func(nodes,edges,node);if Is_DirectedGraph(nodes,edges) and node in nodes thenA := {nd : [node,nd] in edges};while (A /= B) doB := A;
A := A + {n: nd in A, [nd,n] in edges};end;end;end;!idsUndirectedReach := func(nodes,edges,node);if Is_UndirectedGraph(nodes,edges) and node in nodes thenA := {nd: {node,nd} in edges};!clearwhile (A /= B) doB := 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 thenA := {nd: nd in nodes | {node,nd} in edges};while (A /= B) doB := A;A := A + {n: nd in A | {nd,n} in edges};end;end;end;!pp DirectedReach
nodes := {'a','b','c','d','e'};!clearDirectedReach := func(nodes,edges,node);if Is_DirectedGraph(nodes,edges) and node in nodes thenA := {nd : [node,nd] in edges};while (A /= B) doB := A;A := A + {n: nd in A, [nd,n] in edges};end;end;
-
7/27/2019 ISETL functions
20/82
end;!pp UndirectedReachUndirectedReach := func(nodes,edges,node);if Is_UndirectedGraph(nodes,edges) and node in nodes thenA := {nd: nd in nodes | {node,nd} in edges};while (A /= B) doB := A;A := A + {n: nd in A | {nd,n} in edges};end;end;end;!pp UndirectedReachnodes := {'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 UndirectedReachUndirectedReach := func(nodes,edges,node);if Is_UndirectedGraph(nodes,edges) and node in nodes thenA := {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 DirectedReachDirectedReach := func(nodes,edges,node);if Is_DirectedGraph(nodes,edges) and node in nodes thenA := {nd: [node,nd] in edges};while (A /= B) doB := 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};
-
7/27/2019 ISETL functions
21/82
!clear{n: n in nodes | ['a',n] in edges};DirectedReach := func(nodes,edges,node);if Is_DirectedGraph(nodes,edges) and node in nodes thenA := {nd: nd in nodes | [node,nd] in edges};while (A /= B) doB := 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 thenA := {nd: nd in nodes | {node,nd} in edges};while (A /= B) doB := 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) doB := 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) thenreturn UndirectedReach(nodes,edges,arb(nodes)) = nodes;
elseif if Is_DirectedGraph(nodes,edges) thenreturn DirectedReach(nodes,edges,arb(nodes)) = nodes;else return false;end;!clearend;!clearStronglyConnected := func(nodes,edges);if Is_DirectedGraph(nodes,edges) thenreturn UndirectedReach(nodes,edges,arb(nodes)) = nodes;
-
7/27/2019 ISETL functions
22/82
elseif if Is_DirectedGraph(nodes,edges) thenreturn DirectedReach(nodes,edges,arb(nodes)) = nodes;elseif if Is_DirectedGraph(nodes,edges) thenreturn DirectedReach(nodes,edges,arb(nodes)) = nodes;else return false;end;!clearStronglyConnected := func(nodes,edges);if Is_UndirectedGraph(nodes,edges) thenreturn UndirectedReach(nodes,edges,arb(nodes)) = nodes;elseif if Is_DirectedGraph(nodes,edges) thenreturn DirectedReach(nodes,edges,arb(nodes)) = nodes;else return false;end;!clearStronglyConnected := func(nodes,edges);if Is_UndirectedGraph(nodes,edges) thenreturn UndirectedReach(nodes,edges,arb(nodes)) = nodes;elseif if Is_DirectedGraph(nodes,edges) thenreturn DirectedReach(nodes,edges,arb(nodes)) = nodes;elsereturn false;end;!clear
StronglyConnected := func(nodes,edges);if Is_UndirectedGraph(nodes,edges) thenreturn UndirectedReach(nodes,edges,arb(nodes)) = nodes;elseif Is_DirectedGraph(nodes,edges) thenreturn DirectedReach(nodes,edges,arb(nodes)) = nodes;elsereturn false;end;end;StronglyConnected(nodes,edges);edges;!pp DirectedReachDirectedReach := func(nodes,edges,node);
if Is_DirectedGraph(nodes,edges) and node in nodes thenA := {nd: nd in nodes | [node,nd] in edges} with node;while (A /= B) doB := A;A := A + {n: nd in A, n in nodes | [nd,n] in edges};end;end;return A;end;!pp UndirectedReachUndirectedReach := func(nodes,edges,node);if Is_UndirectedGraph(nodes,edges) and node in nodes thenA := {nd: nd in nodes | {node,nd} in edges} with node;
while (A /= B) doB := 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
-
7/27/2019 ISETL functions
23/82
Is_RootedTree := func(nodes,edges);return Is_UndirectedGraph(nodes,edges)and StronglyConnected(nodes,edges) and #edges = #nodes - 1;end;!pp StronglyConnectedStronglyConnected := func(nodes,edges);if Is_UndirectedGraph(nodes,edges) thenreturn forall node in nodes | UndirectedReach(nodes,edges,node) = nodes;elseif Is_DirectedGraph(nodes,edges) thenreturn forall node in nodes | DirectedReach(nodes,edges,node) = nodes;elsereturn 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;!clearSimplyConnected := 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 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;
!pp Z:\DiscreteStructures\myfuncs.txt Is_DirectedEdge!pp Is_DirectedEdge Z:\DiscreteStructures\myfuncs.txt!pp Is_UndirectedEdge!pp Is_DirectedGraph!pp Is_UndirectedGraphDirectedReach := func(nodes,edges,node);if Is_DirectedGraph(nodes,edges) and node in nodes thenA := {nd: nd in nodes | [node,nd] in edges} with node;while (A /= B) doB := A;
-
7/27/2019 ISETL functions
24/82
A := A + {n: nd in A, n in nodes | [nd,n] in edges};end;return A;end;end;!pp DirectedReach!pp!pp DirectedReachUndirectedReach := func(nodes,edges,node);if Is_UndirectedGraph(nodes,edges) and node in nodes thenA := {nd: nd in nodes | {node,nd} in edges} with node;while (A /= B) doB := A;A := A + {n: nd in A, n in nodes | {nd,n} in edges};end;return A;end;end;!pp UndirectedReach Z:\DiscreteStructures\myfuncs.txtStronglyConnected := func(nodes,edges);if Is_UndirectedGraph(nodes,edges) thenreturn 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;elsereturn false;end;end;!pp StronglyConnectedSimplyConnected := func(nodes,edges);return Is_DirectedGraph(nodes,edges) and exists node in nodes | DirectedReach(nodes,edges,node) = nodes;end;!pp SimplyConnectedIs_RootedTree := func(nodes,edges);return SimplyConnected(nodes,edges) and #edges = #nodes - 1;
end;PossibleRoots := func(nodes,edges);if Is_RootedTree(nodes,edges) then;!clearPossibleRoots := func(nodes,edges);if Is_RootedTree(nodes,edges) thenreturn {n: n in nodes | DirectedReach(nodes,edges,node) = nodes};end;end;!pp Is_RootedTree!pp PossibleRootsParent := 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 := {['dedges := {['d','e'],['e','b'],['e','c'],['b','a']};!clearedges := {['d','e'],['e','b'],['e','c'],['b','a']};Parent(nodes,edges);Parent('d');
-
7/27/2019 ISETL functions
25/82
Parent(nodes,edges)("d");Parent(nodes,edges)("e");PathFromRoot := func(nodes,edges);if Is_RootedTree(nodes,edges) thenPathFromRoot := func(node,parent);!clearPathFromRoot := 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 thel = [node];while(parent(par) /= OM)par := parent(node);!clearPathFromRoot := 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$ 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 thel := [node];while(parent(par) /= OM)par := parent(node);!clearPathFromRoot := 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$ 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
l := [node];par := parent(node);while(par /= OM)l := [par] + l;!clearPathFromRoot := 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$ 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 thepath := [node];par := parent(node);while(par /= OM) dopath := [par] + path;par := parent(par);
-
7/27/2019 ISETL functions
26/82
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 thepath := [];while(node /= OM) dopath := [node] + path;node := parent(node);end;return path;end;PathFromRoot('a',Parent(nodes,edges));!pp PathFromRootmin;max;lo;!pp lo
!pp!pp lolo;!ids!locker!lockedMakeCounter := 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;
-
7/27/2019 ISETL functions
27/82
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!recordIs_DirectedEdge := func(nodes,edge);
return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subset 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);
-
7/27/2019 ISETL functions
28/82
if Is_DirectedGraph(nodes,edges) and node in nodes thenA := {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) thenreturn 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 rootlocal 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
-
7/27/2019 ISETL functions
29/82
$ 2) in the fringe and adjacent to a node in marked$ 3) can be reached from a node in the fringe
marked := {};fringe := {root};$ loopwhile fringe /= {} do
take node from fringe;marked := marked with node;for v in AdjacentNodes(node) do
if v notin marked thenfringe := 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 problemlocal Fill, Empty, Pour;
Fill := func(state,i);!clear
!i Z:\DiscreteStructures\myfuncs.txt!record!i Z:\DiscreteStructures\myfuncs.txt!recordIs_DirectedEdge := func(nodes,edge);
return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subset 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 thenA := {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;
-
7/27/2019 ISETL functions
30/82
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 rootlocal 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};$ loopwhile fringe /= {} do
take node from fringe;marked := marked with node;for v in AdjacentNodes(node) do
if v notin marked then
-
7/27/2019 ISETL functions
31/82
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 problemlocal 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 jamount := 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!recordIs_DirectedEdge := func(nodes,edge);
return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subset 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
);
-
7/27/2019 ISETL functions
32/82
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) thenreturn forall node in nodes | UndirectedReach(nodes,edges,node) = nodes;
elseif Is_DirectedGraph(nodes,edges) thenreturn forall node in nodes | DirectedReach(nodes,edges,node) = nodes;
elsereturn 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 rootlocal marked, fringe, node;
-
7/27/2019 ISETL functions
33/82
$ 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};$ loopwhile fringe /= {} do
take node from fringe;marked := marked with node;for v in AdjacentNodes(node) do
if v notin marked thenfringe := 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 problemlocal 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 jamount := 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 funcend 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
-
7/27/2019 ISETL functions
34/82
!recordIs_DirectedEdge := func(nodes,edge);
return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subset 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;
-
7/27/2019 ISETL functions
35/82
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 rootlocal 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 := {};$ loopwhile fringe /= {} do
take node from fringe;marked := marked with node;for v in AdjacentNodes(node) do
if v notin marked thenfringe := 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 problemlocal 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 jamount := min(capBucket(j)-state(j),state(i));state(i) := state(i) - amount;state(j) := state(j) + amount;return state;
end;
-
7/27/2019 ISETL functions
36/82
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 funcend 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);!clearbtree := ReachTree([0,0],bgraph);
bnodes := domain(btree) + range(btree);Is_RootedTree(bnodes,btree);bnodes;btree;#btree;bgraph;!pp bgraphbgraph([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 rootlocal 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 := {};$ loopwhile 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) thenfringe := 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));
-
7/27/2019 ISETL functions
37/82
*** btree := ReachTree([0,0],MkBucketNbrs(Buckets));!clearbtree := ReachTree([0,0],MakeBucketNbrs(Buckets));*** btree := ReachTree([0,0],MakeBucketNbrs);!clearbtree := 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_RootedTreeSimplyConnected(bnodes,btree);!pp SimplyConnectedbtree := {[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;
-
7/27/2019 ISETL functions
38/82
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 rootlocal marked, fringe, node;
marked := {};!clear
!pp SolveBucketNumbers
!pp SolveBucketProblemReachTreeQ := 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 rootlocal 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 rootlocal 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
-
7/27/2019 ISETL functions
39/82
$ 3) can be reached from nodes in the fringe$ loopwhile not IsEmptyH(fringe) do
node := Take(fringe);marked := marked with node;for v in Neighbors(node) do
if v notin marked thenPut(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 NewQueueNewQueue := 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;
-
7/27/2019 ISETL functions
40/82
IsEmptyH := func(holder);$ requires:$ modifies: nothing$ effects :
return holder("empty?")();end;> NewQueue := func();!cleartree := 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 rootlocal 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
$ loopwhile not IsEmptyH(fringe) do
node := Take(fringe);marked := marked with node;for v in Neighbors(node) do
if v notin marked thenPut(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-objectlocal stack, Push, Pop, IsEmptyH;
stack := [];Push := proc(x);
stack := [x] + stack; $ puts x at top of stackend;Pop := func();
local x;take x fromb stack; $ takes x from top of stackreturn x;
end;IsEmptyH := func();
-
7/27/2019 ISETL functions
41/82
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 rootlocal marked, edges, fringe, node;
marked := {};fringe := NewHolder();edges := {};Put(root,fringe);
$ The following is true before each iteration of the $ loop
-
7/27/2019 ISETL functions
42/82
$ 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
$ loopwhile not IsEmptyH(fringe) do
node := Take(fringe);marked := marked with node;for v in Neighbors(node) do
if v notin marked thenPut(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-objectlocal stack, Push, Pop, IsEmptyH;stack := [];Push := proc(x);
stack := [x] + stack; $ puts x at top of stackend;Pop := func();
local x;take x fromb stack; $ takes x from top of stackreturn 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.
-
7/27/2019 ISETL functions
43/82
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 := {};$ loopwhile fringe /= [] do
take node fromb fringe;marked := marked with node;
for v in AdjacentNodes(node) doif v notin marked and v notin domain(edges) thenfringe := 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};
-
7/27/2019 ISETL functions
44/82
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};!clearp := {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;!lockedIs_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 thenif k=0 then
return {[]};elseif S = {} thenreturn {};
elsereturn {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 $ 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_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 then $ tests alph and N
nodes := AllLists(alph,N-1);edges := {[n1,n2]: n1, n2 in nodes | n1(2..N-1) = n2(1..N-2)};
-
7/27/2019 ISETL functions
45/82
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 then $ 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} subset 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;
-
7/27/2019 ISETL functions
46/82
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 waypath := [];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 rootlocal 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 := {};$ loopwhile 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) thenfringe := fringe with v;edges := edges with [v,node];
end;end;
end;return edges;
end;
MkBucketNbrs := func(capBucket);
-
7/27/2019 ISETL functions
47/82
$ 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 problemlocal 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 jamount := 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];
!clearend;OutDegree := func(node)
return #[l: l in edges | l(1) = node];end;
if StronglyConnected(nodes,edges) thenreturn 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
-
7/27/2019 ISETL functions
48/82
$ set edgesedge := 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!clearIs_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 thenif k=0 thenreturn {[]};
elseif S = {} thenreturn {};
elsereturn {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} subset 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;
-
7/27/2019 ISETL functions
49/82
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 waypath := [];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 rootlocal 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 := {};$ loopwhile fringe /= [] do
-
7/27/2019 ISETL functions
50/82
take node fromb fringe;marked := marked with node;for v in AdjacentNodes(node) do
if v notin marked and v notin domain(edges) thenfringe := 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 problemlocal 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 jamount := 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];
!clearend;OutDegree := func(node)
-
7/27/2019 ISETL functions
51/82
return #[l: l in edges | l(1) = node];end;
if StronglyConnected(nodes,edges) thenreturn 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!clearIs_DirectedEdge := func(nodes,edge);
return is_set(nodes) and is_list(edge) and #edge = 2 and {x: x in edge} subset 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;
-
7/27/2019 ISETL functions
52/82
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) dopath := [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 rootlocal 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 := {};$ loopwhile fringe /= [] do
take node fromb fringe;
-
7/27/2019 ISETL functions
53/82
marked := marked with node;for v in AdjacentNodes(node) do
if v notin marked and v notin domain(edges) thenfringe := 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 problemlocal 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 jamount := 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 funcend 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];
!clearend;OutDegree := func(node)
return #[l: l in edges | l(1) = node];
-
7/27/2019 ISETL functions
54/82
end;
if StronglyConnected(nodes,edges) thenreturn 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!clearIs_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
-
7/27/2019 ISETL functions
55/82
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 rootlocal 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 := {};$ loopwhile 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) thenfringe := fringe with v;edges := edges with [v,node];
end;
-
7/27/2019 ISETL functions
56/82
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 problemlocal 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 jamount := 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 funcend 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
-
7/27/2019 ISETL functions
57/82
et nodes;end;
Is_UndirectedEdge := func(nodes,edge);return is_set(nodes) and is_set(edge) and