isetl functions

Upload: jacob-greenfield

Post on 14-Apr-2018

230 views

Category:

Documents


0 download

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