-
-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
20c3bdc
commit d6e2316
Showing
5 changed files
with
99 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Hints | ||
|
||
## General | ||
|
||
- A tree is a recursive data structure that has two cases: | ||
- `nil`: a leaf node, which doesn't have a value | ||
- `node(Left, Value, Right)`: a regular node, which has a value and a left and right node | ||
- For both pre-order and in-order traversal, you'll need to define rules that handle the two cases for trees |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,22 @@ | ||
# Instructions append | ||
|
||
Try using Prolog DCGs. **But watch out for left recursion!** | ||
You should implement this exercise using a definite clause grammar (DGC). | ||
DCGs can be used not only to parse sequences (lists), but also to generate, complete and check those sequences. | ||
|
||
For extra bonus points: | ||
## Library | ||
|
||
Make tree_traversals also work in "reverse," i.e. one of the traversal | ||
lists is a variable, for example: | ||
The stub implementation files includes the following line: | ||
|
||
```prolog | ||
:- use_module(library(dcg/basics)). | ||
``` | ||
?- tree_traversals(node(nil,5,node(nil,9,nil)),Pre,[5,9]) | ||
Pre = [5, 9] | ||
``` | ||
|
||
and also in-order traversal as variable and pre-order as a list. | ||
This ensures that the `dcg/basics` library can be used, which should be enough to solve this exercise. | ||
|
||
## Resources | ||
|
||
The following are useful resources to get started with DCG's in Prolog: | ||
|
||
This should be simple using DCGs. | ||
- [metalevel.at](https://www.metalevel.at/prolog/dcg) | ||
- [wikipedia](https://en.wikipedia.org/wiki/Definite_clause_grammar) | ||
- [swipl](https://www.swi-prolog.org/pldoc/man?section=DCG) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,12 @@ | ||
% Reference Implementation | ||
% | ||
% Rebuilding Binary Trees from Traversals (medium) | ||
% Inorder and Preorder | ||
% | ||
:- use_module(library(dcg/basics)). | ||
|
||
/* Default content can be this stub. | ||
tree_traversals(Tree, Preorder, Inorder) :- fail. | ||
*/ | ||
preorder(nil) --> []. | ||
preorder(node(L, V, R)) --> [V], preorder(L), preorder(R). | ||
|
||
preorder(nil) --> []. | ||
preorder(node(L,V,R)) --> [V],preorder(L),preorder(R). | ||
|
||
% Left recursive definitions can cause infinite loops. | ||
% E.g. in a naive implementation | ||
% ?- phrase(inorder(T),[a,b,c]). | ||
% unifies once and then loops. | ||
% (remove extra arguments from inorder//3 below to see this in action). | ||
% Notice the second rule directly consumes one item from the traversal. | ||
% The loop can be broken by applying the second rule only if there are | ||
% still items in the traversal. To encode this requirement the traversal's | ||
% length can be used to count the number of times the 2nd rule has been | ||
% applied. Each time the 2nd rule is applied an _arbitrary_ item is dropped | ||
% ([_|B1]) corresponding to the one item directly consumed by the rule. When | ||
% the traversal has been completely consumed the extra argument is [] which | ||
% does not match [_|B1] so the recursion is "bounded". | ||
inorder(nil, Ls,Ls) --> []. | ||
inorder(node(L,V,R), [_|B1],B3) --> inorder(L, B1,B2),[V],inorder(R, B2,B3). | ||
inorder(nil) --> []. | ||
inorder(node(L, V, R)) --> inorder(L), [V], inorder(R). | ||
|
||
tree_traversals(Tree, Preorder, Inorder) :- | ||
phrase(preorder(Tree),Preorder), | ||
phrase(inorder(Tree,Inorder,_),Inorder). | ||
phrase(preorder(Tree), Preorder), | ||
phrase(inorder(Tree), Inorder), | ||
!. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
:- use_module(library(dcg/basics)). | ||
|
||
tree_traversals(Tree, Preorder, Inorder). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters