1 / 27

Formal Models of Computation Part II The Logic Model

Formal Models of Computation Part II The Logic Model. Lecture 7 – Trees and graphs. Trees. Trees are important data structures Binary trees: each node has at most two daughters Binary trees can be recursively defined as An empty tree is a binary tree (represented as “nil”)

Download Presentation

Formal Models of Computation Part II The Logic Model

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Formal Models of ComputationPart IIThe Logic Model Lecture 7 – Trees and graphs

  2. Trees • Trees are important data structures • Binary trees: each node has at most two daughters • Binary trees can be recursively defined as • An empty tree is a binary tree (represented as “nil”) • A binary tree is a node with two subtrees • In Prolog, we can represent binary trees as bTree(Node,SubTreeL,SubTreeR) where SubTreeL and SubTreeR are (recursively) binary trees. • Convention for the empty tree: nil formal models of computation

  3. Trees (Cont’d) a b c d e f nil nil nil nil nil nil nil • For instance, the binary tree • Can be represented in Prolog as bTree(a, bTree(b, bTree(d,nil,nil), bTree(e,nil,nil)), bTree(c, bTree(f,nil,nil), nil)). • Remarks: • There is nothing special about the bTree name! We could have used “foo” or “bar” ; • Identations are for the benefit of humans, i.e., to improve visualisation! formal models of computation

  4. Trees (Cont’d) • Let’s write a program to visit the nodes of a binary tree in pre-order • Visit (write) parent node, then • Visit subtree on the left (using the same policy), then • Visit subtree on the right (ditto) • In Prolog: preOrder(nil). % empty tree? preOrder(bTree(N,L,R)):- % not empty tree? write(N), % write node N nl, % skip a line preOrder(L), % recursion on left tree preOrder(R). % recursion on right tree formal models of computation

  5. Trees (Cont’d) • Let’s alter the previous program • Enable it to collect in a list the nodes of the tree: • This portion defines the main flow of execution • Add an argument to hold the list to be built: • Decide on what to do with each case… traverse(nil). % empty tree? traverse(bTree(N,L,R)):- % not empty tree? traverse(L), % recursion on left tree traverse(R). % recursion on right tree traverse(nil,List0). traverse(bTree(N,L,R),List1):- traverse(L,List2), traverse(R,List3). formal models of computation

  6. Trees (Cont’d) • What happens on the base (empty tree) case? • What value should a list of nodes have when the tree is empty? Answer: the empty list! collect(nil,List0):- % if empty tree List0 = []. % list is empty collect(bTree(N,L,R),List1):- collect(L,List2), collect(R,List3). formal models of computation

  7. Trees (Cont’d) • What happens on the recursive case? • We must relate N and the resulting lists of L and R • Node N must be the head of the final resulting list • There are two resulting lists List2 and List3 • These two lists must be combined (append!) collect(nil,List0):- % if empty tree List0 = []. % list is empty collect(bTree(N,L,R),List1):- List1 = [N|List4], % N is the head collect(L,List2), % get nodes of L collect(R,List3), % get nodes of R append(List2,List3,List4). % append them! formal models of computation

  8. Trees (Cont’d) • More compact: collect(nil,[]). % if empty tree collect(bTree(N,L,R),[N|Ns]):- % otherwise collect(L,LNs), % get nodes of L collect(R,RNs), % get nodes of R append(LNs,RNs,Ns). % append them! formal models of computation

  9. Trees (Cont’d) • Change program to count nodes of tree • Initial program establishes the flow of execution • As the tree is traversed, computations can take place! • To compute/show results, an argument must be inserted in every goal: traverse(nil). traverse(bTree(N,L,R)):- traverse(L), traverse(R). count(nil,Arg1). count(bTree(N,L,R),Arg2):- count(L,Arg3), count(R,Arg4). formal models of computation

  10. Trees (Cont’d) • The inserted arguments must be • Defined or • Related to each other count(nil,Arg1):- define(Arg1). count(bTree(N,L,R),Arg2):- relate1(Arg2,Arg3,Arg4), count(L,Arg3), count(R,Arg4), relate2(Arg2,Arg3,Arg4). formal models of computation

  11. Trees (Cont’d) • In this specific case, we have: • More compact: count(nil,SNs):- SNs = 0. count(bTree(N,L,R),SNs):- count(L,SLNs), count(R,SRNs), SNs is 1 + SLNs + SRNs. count(nil,0). % empty tree? no. nodes is 0 count(bTree(N,L,R),SNs):- % otherwise count(L,SLNs), % get no nodes of left tree count(R,SRNs), % get no nodes of right tree SNs is 1 + SLNs + SRNs. % add them up plus 1 formal models of computation

  12. Graphs a b c e d f • Graphs are a generalisation of trees: • Nodes can have many parents and many children • Example: • A mathematical definition: • A graph G = (N,E ) is • A set of nodes N = {a1 ,…, an} • A set of edges E N  N formal models of computation

  13. Graphs (Cont’d) a b c e d f • A Prolog representation for graphs • Based on the previous mathematical definition: nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). formal models of computation

  14. Graphs (Cont’d) • Let’s write a program to check for paths • A path between O and D exists iff: • There is an edge (O,D) (i.e., a direct path) OR • There is an edge (O,I) from the origin to an intermediate node I and there is a path from I to D • In Prolog: path(O,D):- % there is a path between O and D edge(O,D). % if there is an edge between them path(O,D):- % otherwise, edge(O,I), % there is an intermediary node I path(I,D). % with a path between I and D formal models of computation

  15. Graphs (Cont’d) path(O1,D1):- edge(O1,D1). {O1/a,D1/e} unification path(O1,D1):- edge(O1,D1). {O1/a,D1/e} Fail!! • Execution: nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D):- edge(O,D). path(O,D):- edge(O,I), path(I,D). Backtracks… ?- path(a,e). formal models of computation

  16. Graphs (Cont’d) path(O1,D1):- edge(O1,I1), path(I1,D1). {O1/a,D1/e} unification path(b,e) • Execution: nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D):- edge(O,D). path(O,D):- edge(O,I), path(I,D). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D):- edge(O,D). path(O,D):- edge(O,I), path(I,D). path(O1,D1):- edge(O1,I1), path(I1,D1). {O1/a,D1/e,I1/b} path(O1,D1):- edge(O1,I1), path(I1,D1). {O1/a,D1/e,I1/b} ?- path(a,e). formal models of computation

  17. Graphs (Cont’d) path(O1,D1):- edge(O1,D1). {O1/b,D1/e} unification path(O1,D1):- edge(O1,D1). {O1/b,D1/e} Fail!! • Execution: nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D):- edge(O,D). path(O,D):- edge(O,I), path(I,D). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D):- edge(O,D). path(O,D):- edge(O,I), path(I,D). Backtracks… path(b,e) formal models of computation

  18. Graphs (Cont’d) path(O1,D1):- edge(O1,I1), path(I1,D1). {O1/b,D1/e} unification path(c,e) • Execution: nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D):- edge(O,D). path(O,D):- edge(O,I), path(I,D). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D):- edge(O,D). path(O,D):- edge(O,I), path(I,D). path(O1,D1):- edge(O1,I1), path(I1,D1). {O1/b,D1/e,I1/c} path(O1,D1):- edge(O1,I1), path(I1,D1). {O1/a,D1/e,I1/c} path(b,e) formal models of computation

  19. Graphs (Cont’d) path(O1,D1):- edge(O1,D1). {O1/c,D1/e} unification • Execution: nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D):- edge(O,D). path(O,D):- edge(O,I), path(I,D). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D):- edge(O,D). path(O,D):- edge(O,I), path(I,D). path(O1,D1):- edge(O1,D1). {O1/c,D1/e} path(c,e) path(c,e) ?- path(a,e). yes ?- formal models of computation

  20. Graphs (Cont’d) • Predicate path can be used in 4 different ways: • path(a,e): is there a path between a and e? • path(a,D): where can we get from a? • path(O,e): where can we start a journey to e? • path(O,D): all possible tours • Problems: the previous program may loop! • If there are cycles in the path, then program may loop forever… • We can improve the previous program to keep track of where we’ve been and avoid loops. • Store in a list the nodes that have been visited formal models of computation

  21. Graphs (Cont’d) “not provable” • Reuse previous program and add functionality: path(O,D,Path):- % as before edge(O,D). % Path has no use here path(O,D,Path):- % same as before edge(O,I), % get intermediate node \+ member(I,Path), % that is not already in Path path(I,D,[I|Path]). % update path and carry on formal models of computation

  22. Graphs (Cont’d) Loop: a-b-a!! Initial value of Path • Same graph with one node added: edge(b,a) nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). ?- path(a,e,[a]). formal models of computation

  23. Graphs (Cont’d) path(O1,D1,_):- edge(O1,D1). {O1/a,D1/e} unification path(O1,D1,_):- edge(O1,D1). {O1/a,D1/e} Fail!! • Execution: nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). Backtracks… ?- path(a,e,[a]). formal models of computation

  24. Graphs (Cont’d) path(O1,D1,Path1):- edge(O1,I1), \+ member(I1,Path1), path(I1,D1,[I1|Path1]). {O1/a,D1/e,Path1/[a]} unification path(b,e,[b,a]) • Execution: nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). path(O1,D1,Path1):- edge(O1,I1), \+ member(I1,Path1), path(I1,D1,[I1|Path1]). {O1/a,D1/e,Path1/[a],I1/b} path(O1,D1,Path1):- edge(O1,I1), \+ member(I1,Path1), path(I1,D1,[I1|Path1]). {O1/a,D1/e,Path1/[a],I1/b} path(O1,D1,Path1):- edge(O1,I1), \+ member(I1,Path1), path(I1,D1,[I1|Path1]). {O1/a,D1/e,Path1/[a],I1/b} ?- path(a,e,[a]). formal models of computation

  25. Graphs (Cont’d) path(O2,D2,Path2):- edge(O2,I2), \+ member(I2,Path2), path(I2,D2,[I2|Path2]). {O2/b,D2/e,Path2/[b,a]} unification path(O2,D2,Path2):- edge(O2,I2), \+ member(I2,Path2), path(I2,D2,[I2|Path2]). {O2/a,D2/e,Path2/[b,a],I2/a} Fail!! • Execution: nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). path(O2,D2,Path2):- edge(O2,I2), \+ member(I2,Path2), path(I2,D2,[I2|Path2]). {O2/b,D2/e,Path2/[b,a],I2/a} path(O2,D2,Path2):- edge(O2,I2), \+ member(I2,Path2), path(I2,D2,[I2|Path2]). {O2/a,D2/e,Path2/[b,a],I2/a} It fails because node a has already been visited – it is in the Path followed so far. Prolog backtracks to the previous goal and tries another edge! path(b,e,[b,a]). formal models of computation

  26. Graphs (Cont’d) path(O2,D2,Path2):- edge(O2,I2), \+ member(I2,Path2), path(I2,D2,[I2|Path2]). {O2/b,D2/e,Path2/[b,a]} unification path(c,e,[c,b,a]) • Execution: nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). path(O2,D2,Path2):- edge(O2,I2), \+ member(I2,Path2), path(I2,D2,[I2|Path2]). {O2/b,D2/e,Path2/[b,a],I2/c} path(O2,D2,Path2):- edge(O2,I2), \+ member(I2,Path2), path(I2,D2,[I2|Path2]). {O2/a,D2/e,Path2/[b,a],I2/c} path(O2,D2,Path2):- edge(O2,I2), \+ member(I2,Path2), path(I2,D2,[I2|Path2]). {O2/a,D2/e,Path2/[b,a],I2/c} path(b,e,[b,a]). formal models of computation

  27. Graphs (Cont’d) • Execution: path(O3,D3,Path3):- edge(O3,I3), \+ member(I3,Path3), path(I3,D3,[I3|Path3]). {O3/c,D3/e,Path3/[c,b,a]} nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). nodes([a,b,c,d,e,f]). edge(a,b). edge(a,d). edge(a,f). edge(b,a). edge(b,c). edge(b,f). edge(c,e). edge(f,d). edge(f,e). path(O,D,_):- edge(O,D). path(O,D,Path):- edge(O,I), \+ member(I,Path), path(I,D,[I|Path]). Computation goes on until it finally reaches destination. The path is added with each node visited thus avoiding coming back to a visited node. path(c,e,[c,b,a]) formal models of computation

More Related