diff --git a/docs/bql.md b/docs/bql.md index 30cdb36d..6e720555 100644 --- a/docs/bql.md +++ b/docs/bql.md @@ -39,7 +39,7 @@ CREATE GRAPH ?a; ``` The name of the graph is represented by a non interpreted binding (more on -this will be discussed in the next section.) Hence, on the previous example +this will be discussed in the next section.) Hence, in the previous example the statement would create a graph named ```?a```. You can create multiple graphs in a single statement as shown in the example below. @@ -47,8 +47,8 @@ graphs in a single statement as shown in the example below. CREATE GRAPH ?a, ?b, ?c; ``` -If you try to create a graph that already exist, it will fail saying that -the graph already exist. You should not expect that creating multiple graphs +If you try to create a graph that already exists, it will fail saying that +the graph already exists. You should not expect that creating multiple graphs will be atomic. If one of the graphs fails, there is no guarantee that others will have been created, usually failing fast and not even attempting to create the rest. @@ -56,7 +56,7 @@ the rest. ## Dropping an Existing Graph Existing graphs can be dropped via the ```DROP``` statement. Be *very* -*careful* when dropping graphs. The operation is assume to be irreversible. +*careful* when dropping graphs. The operation is assumed to be irreversible. Hence, all data contained in the graph with be lost. You can drop a graph via: ``` @@ -80,11 +80,11 @@ been created, usually failing fast and not even attempting to create the rest. BQL relies on the concept of binding, or a place holder to represent a value. Bindings can be read as immutable variables given scoped context. Bindings -starting with a '?' and it is followed by letters or digits. Some examples of +start with a '?' and are followed by letters or digits. Some examples of bindings are: ```?foo```, ```?bar```, ```?id12```. -Bindings, once they take a value in a context, they cannot bind to a different -value. Bindings allow to express graph matching patterns. The simplest form +Bindings, once they take a value in a context, cannot bind to a different +value. Bindings allow expression of graph matching patterns. The simplest form of a graph pattern is the fully specified triple. ``` @@ -92,16 +92,16 @@ of a graph pattern is the fully specified triple. ``` The above graph pattern would only match triples with the specified subject, -predicated, and object. A peculiarity of the above pattern is that since +predicate, and object. A peculiarity of the above pattern is that since the predicate is immutable, the above pattern is the equivalent of checking -if that triple exist on the graph. The equivalent of the above pattern for a -temporal predicate would look like as: +if that triple exists on the graph. The equivalent of the above pattern for a +temporal predicate would look like the following: ``` /user "follows"@[2006-01-02T15:04:05.999999999Z07:00] /user ``` -The above pattern checks if that triple exist and it is anchored at that +The above pattern checks if that triple exists and if it is anchored at that particular time. It is important not to confuse bindings with time ranges for temporal predicates. A time range is specified as shown below. @@ -115,10 +115,10 @@ for temporal predicates. A time range is specified as shown below. /user "follows"@[2006-01-01T15:04:05.999999999Z07:00, 2006-01-02T15:04:05.999999999Z07:00] /user ``` -The first pattern asks if Joe at any point in time ever followed Mary. The -second pattern asks if Joe ever followed Mary after a certain date, as opposite +The first pattern asks if Joe, at any point in time, ever followed Mary. The +second pattern asks if Joe ever followed Mary after a certain date, as opposed to the third pattern that asks if Joe ever followed Mary before a certain date. -Finally, the fourth pattern ask if Joe followed Mary between two specific dates. +Finally, the fourth pattern asks if Joe followed Mary between two specific dates. Bindings represent potential values in a given context. For instance, @@ -126,7 +126,7 @@ Bindings represent potential values in a given context. For instance, /user "follows"@[,] ?user ``` -represent a pattern that matches against all the users that Joe followed ever. +represents a pattern that matches against all the users that Joe followed ever. As opposed to ``` @@ -134,7 +134,7 @@ As opposed to ``` which represents all the users that ever followed Mary. You could also ask about -all the predicate about Joe related to Mary, we would just write +all the predicates about Joe related to Mary, we would just write ``` /user ?p /user @@ -152,16 +152,16 @@ express such pattern as You can combine multiple graph patterns together using '.' to separate clauses. The important thing to keep in mind is that the above composite clause represents a single context. That means that ?x is a binding that once -instantiated, it cannot change the value in that context. Imagine Joe is the +instantiated, cannot change the value in that context. Imagine Joe is the parent of Peter and Peter is the parent of Mary. Once the first part of the -clause is match againt Joe is the parent of Peter, ```?grandparent``` gets -binded against Joe and ```?x``` against Peter. To satisfy the second part of -the composite clause we now need to find triples where the subject is Peter -(remember that once the value is binded in a context it cannot change) a -predicate saying it is the parent of, and then if that exist then -```?grand_child``` would get binded and take the value of Mary. - -As we will see in later examples, bindings can be use to also identify +clause is matched against Joe as the parent of Peter, ```?grandparent``` gets +bound against Joe and ```?x``` against Peter. To satisfy the second part of +the composite clause, we now need to find triples where the subject is Peter +(remember that once the value is bound in a context it cannot change) and the +predicate is parent of. If one exists, then ```?grand_child``` would get bound +and take the value of Mary. + +As we will see in later examples, bindings can also be used to identify nodes, literals, predicates, or time anchors. ## Querying Data from graphs @@ -177,10 +177,10 @@ of a query is expressed as follows }; ``` -The above query would return all the grandchildren of Joe. BQL users binding -notation to identify a graph to use. It over uses the '?' and it just indicates -the name of the graph. In the above example that query would be run against -a graph which ID is equal to "?family_tree". You can also query against multiple +The above query would return all the grandchildren of Joe. BQL uses binding +notation to identify a graph to use. It uses the '?' to indicate the name +of the graph. In the above example that query would be run against a graph +which ID is equal to "?family_tree". You can also query against multiple graphs. ``` @@ -191,7 +191,7 @@ graphs. }; ``` -There is no limit on how many variable you may return. You can return multiple +There is no limit on how many variables you may return. You can return multiple variables instead as shown below. ``` @@ -203,9 +203,9 @@ variables instead as shown below. ``` The above query would return all grandparents together with the name of their -grand kids, one pair per row. In some cases it is useful to return a different +grandchildren, one pair per row. In some cases it is useful to return a different name for the variables, and not use the biding name used in the graph pattern -directly. This is achieved using the as keyword as shown below. +directly. This is achieved using the "as" keyword as shown below. ``` SELECT ?grandparent as ?gp, ?grand_child as ?gc @@ -215,13 +215,13 @@ directly. This is achieved using the as keyword as shown below. }; ``` -It is important to note that alias are defined outside the graph pattern scope. -Hence, alias cannot be used in graph patterns. +It is important to note that aliases are defined outside the graph pattern scope. +Hence, aliases cannot be used in graph patterns. -BQL supports basic grouping and aggregation. To achieve this, it is accomplished -via ```group by```. The above query may return duplicates depending on the data +BQL supports basic grouping and aggregation. It is accomplished via +```group by```. The above query may return duplicates depending on the data available on the graph. If we want to get rid of the duplicates we could just -group them as follows to remove the duplicates. +group them as follows. ``` SELECT ?grandparent as ?gp, ?grand_child as ?gc @@ -235,7 +235,7 @@ group them as follows to remove the duplicates. As you may have expected, you can group by multiple bindings or aliases. Also, grouping allows a small subset of aggregates. Those include ```count``` its variant with distinct, and ```sum```. Other functions will be added as needed. -The queries below illustrate how this simple aggregations can be used. +The queries below illustrate how these simple aggregations can be used. ``` SELECT ?grandparent as ?gp, count(?grand_child) as ?gc @@ -246,7 +246,7 @@ The queries below illustrate how this simple aggregations can be used. GROUP BY ?gp; ``` -Would return the number of grand childre per grandparent. However, it would +Would return the number of grandchildren per grandparent. However, it would be better if the distinct version was used to guaranteed that all duplicates resulting on the graph data are removed. The query below illustrates how the distinct variant work. @@ -260,7 +260,7 @@ the distinct variant work. GROUP BY ?gp; ``` -The sum agreegation only works if the binding is done against a literal of type +The sum aggregation only works if the binding is done against a literal of type ```int64``` or ```float64```, as shown on the example below. ``` @@ -271,13 +271,13 @@ The sum agreegation only works if the binding is done against a literal of type } ``` -You can also use ```sum``` to do partial accumulations in the same maner as was +You can also use ```sum``` to do partial accumulations in the same manner as was done in the ```count``` examples above. -Results of the query can be sorted. By default on ascending order based on -the provided variables. The example below orders first by grandparent name -ascending (implicit direction), and then for each equal value descending based -on the grand child name. +Results of the query can be sorted. By default, it is sorted in ascending +order based on the provided variables. The example below orders first by +grandparent name ascending (implicit direction), and for each equal values, +descending based on the grandchild name. ``` SELECT ?grandparent, ?grand_child @@ -288,8 +288,9 @@ on the grand child name. ORDER BY ?grandparent, ?grand_child DESC; ``` -The having modifier allows to filter the returned data further. For instance, -the query below would only return tanks with a capacity bigger than 10. +The "having" modifier allows us to filter the returned data further. For +instance, the query below would only return tanks with a capacity bigger +than 10. ``` SELECT ?tank, ?capacity @@ -327,11 +328,11 @@ certain date. You could write it as ?user "folows"@[2006-01-01T15:04:05.999999999Z07:00,] /user } ``` -You can also imagine that this can become tedious fast if you graph pattern -contains multiple clauses. BQL allows you to specify it a more compact and +You can also imagine that this can become tedious fast if your graph pattern +contains multiple clauses. BQL allows you to specify it in a more compact and readable form using composable ```before```, ```after```, and ```between``` -keywords. They can be composed together using ```not```, ```and```, and ```or``` -operators. +keywords. They can be composed together using ```not```, ```and```, and +```or``` operators. ``` SELECT ?user @@ -343,7 +344,7 @@ operators. AFTER 2006-01-01T15:04:05.999999999Z07:00 ``` -Which is easier to read. It also allow expressing complex global time bounds +This is easier to read. It also allow expressing complex global time bounds that would require multiple clauses and extra bindings. ``` @@ -373,7 +374,7 @@ look like ## Inserting data into graphs -Triples can be inserted into one or more graphs. That can be achieve by just +Triples can be inserted into one or more graphs. This can be achieved by running the following insert statements. ``` diff --git a/docs/bql_practical_examples.md b/docs/bql_practical_examples.md index 2872d398..c81b8a61 100644 --- a/docs/bql_practical_examples.md +++ b/docs/bql_practical_examples.md @@ -18,7 +18,7 @@ each of the example files with a brief description. * [Summarizing and sorting data queries across graphs](../examples/bql/example_2.bql): Sometimes you want to queries data that is stored across multiple graphs. This example shows how you can express queries across multiple graphs, by - simple listing them in the `FORM` clause, and summarize the results + simple listing them in the `FROM` clause, and summarize the results accordingly. It also shows how to sort the resulting tables using via the `ORDER BY` clause. It is important to highlight that BQL `FROM` clause does not express table joins, but the union of the specified graphs. diff --git a/docs/bql_query_planner.md b/docs/bql_query_planner.md index c7e58f50..12d7e3b9 100644 --- a/docs/bql_query_planner.md +++ b/docs/bql_query_planner.md @@ -33,7 +33,7 @@ in the store. The fist clause will be ```true``` if there is a triple supporting that fact in the graph being queried on the store. It will return ```false``` otherwise. It is important that keep this part of the evaluation in mind. When we get to how patterns with multiple clauses are evaluated. Intuitively you can -think of them as follows, a composed patter will be ```true``` if all its +think of them as follows, a composed pattern will be ```true``` if all its clauses are ```true```. It will be ```false``` otherwise. This first clause would translate into planning to execute a simple call to the interface method ```Exist``` to satisfy it. @@ -42,13 +42,13 @@ The second clause is not as specific as the first one. In the example, what would be the object has been replaced by the binding ```?child```. This indicates that we care about the objects that satisfy having ```/user``` as subject and ```"parent-of"@[]``` as a predicate. If such triples exist on -the queried graph, the clause would be ```true```. If there are no triple that +the queried graph, the clause would be ```true```. If there are no triples that would match such a clause, it will evaluate to ```false```. -The binding will take all the possible values available on the graph. This mean -that for a given matching iteration ```?child``` will only have one value across -the pattern. The planner will decide that to resolve such a clause, it will -require to use the ```TriplesForSubjectAndPredicate``` interface method. +The binding will take all the possible values available on the graph. This +means that for a given matching iteration ```?child``` will only have one value +across the pattern. The planner will decide that to resolve such a clause, it +will require to use the ```TriplesForSubjectAndPredicate``` interface method. Let's assume that for the rest of this document our graph will contain the following triples: @@ -62,7 +62,7 @@ contain the following triples: Given the above data, the clause ```/user "parent-of"@[] ?child``` is ```true```. Also, resolving the clause triggered two binding iterations where -```?child``` would be binded to ```/user``` and ```/user``` in +```?child``` would be bound to ```/user``` and ```/user``` in each iteration. ## Specificity of a clause. @@ -83,12 +83,13 @@ the bindings present. | ```/user ?p ?o``` | 1 | | ```?s ?p ?o``` | 0 | -Clauses with _S(c)_=0 indicate clauses that would match the entire graph. +Clauses with _S(c)_= 0 indicate clauses that would match the entire graph. ## Resolving multi clause patterns -Imagine that given the example graph you would like who are the grandchild of -Joe. You can express that query by using a compound pattern form by two clauses. +Imagine that given the example graph you would like to know who the +grandchildren of Joe are. You can express that query by using a compound +pattern form with two clauses. ``` /user "parent-of"@[] ?child . @@ -96,45 +97,45 @@ Joe. You can express that query by using a compound pattern form by two clauses. ``` This pattern contains two clauses. Both need to be satisfied in order to satisfy -the pattern. Another interesting point is that this clauses have a binding +the pattern. Another interesting point is that these clauses have a binding dependency. The first and the second clause in the pattern share the ```?child``` binding. Remember that a binding takes a non mutable value during a binding iteration. This means that we have a few options on how we plan to query the graph at hand to see if we can satisfy this pattern. 1. We get all the children that we can find for Joe, then for each child we - try to see if they are the parent of any other kid. -2. We look for all kids and get the list of parents, then for each of those - parents we try to see if they are the kids of Joe. + try to see if they are the parent of any other person. +2. We look for all children to get the list of parents, then for each of those + parents we try to see if they are a child of Joe. 3. We get all the children of Joe. We also get all parents and children in the graph. We take both sets of data and filter our any children in the Graph - that whose parent is not a children of Joe. + whose parent is not a child of Joe. All three options are valid options that the planner could chose to try to satisfy the given graph pattern. The first one has the benefits of trying to -narrow the amount of data to swift through. The second option would likely yield -large amounts of data to on parents, and then use all that data to find which -of this parents is a child of Joe. Finally, the third option would allow us to -concurrently get the data to satisfy both clauses, but then we will have to +narrow the amount of data to sift through. The second option would likely yield +large amounts of data on parents, and then use all that data to find which of +those parents is a child of Joe. Finally, the third option would allow us to +concurrently get the data to satisfy both clauses, but we will then have to reduce it to find the final answer. -If we look a bit more about each of this clauses, we can see that _S(c)_ of the -first one is 2, whereas the specificity of the second one is 1. It is reasonable -to assume that more specific clauses will return less data. This assumption may -not always hold true, since it depends on the branching factor of our graph, but -it is a good intuition on which build the planner. +If we look a bit more about each of these clauses, we can see that _S(c)_ of +the first one is 2, whereas the specificity of the second one is 1. It is +reasonable to assume that more specific clauses will return less data. This +assumption may not always hold true, since it depends on the branching factor +of our graph, but it is a good intuition on which to build the planner. -## Nave Specificity-Based Query planner +## Naive Specificity-Based Query planner BQL uses a pretty simple planner. It does not use any statistics about the graph queried. The main reason for it is that it may not be available. Remember that the details of the storage are abstracted away by the ```storage``` package. -However, even with such constrains, we can build a pretty efficient planner +However, even with such constraints, we can build a pretty efficient planner that will work efficiently across a wide variety of reasonable connected graphs. The planner (P) will try to satisfy a pattern following the steps described below: -1. P will create a graph where nodes clauses. +1. P will create a graph based on the where clauses. 2. P will add an edge between two clauses if they share a binding. The edge will be directed if and only if the two clauses have different specificity. The direction will go from higher specificity clause to lower specificity one. @@ -150,5 +151,5 @@ The planner (P) will try to satisfy a pattern following the steps described belo 9. If the specificity level is greater or equal than 0, the planner will proceed to step 5. -Once if the process is not aborted, the pattern is satisfied and the query will -return all the values that were binded in the process as a simple table. +If the process is not aborted, the pattern is satisfied and the query will +return all the values that were bound in the process as a simple table. diff --git a/docs/command_line_tool.md b/docs/command_line_tool.md index e027301f..6795f9e3 100644 --- a/docs/command_line_tool.md +++ b/docs/command_line_tool.md @@ -5,10 +5,11 @@ The `bw` command line tool is built via the `tools/vcli/bw` package. You can build the tool by just typing ``` -$ go test ./... && go build ./tools/vcli/bw/... +$ go test github.com/google/badwolf/... && go build github.com/google/badwolf/tools/vcli/bw ``` -Is the test pass successfully you will get the `bw` tool ready to go. +If the test pass successfully, the `bw` tool will be placed in the current +directory. ## Usage @@ -18,7 +19,7 @@ Once built, you will be able to access the commands available by typing: $ bw help ``` -This command will list of available options already. Also, you can always type +This command will list available options. Also, you can always type ``` $ bw help COMMAND @@ -225,15 +226,15 @@ Evaluating 6 stories... done. done ``` -If any of the assertions of a story fails, it will be proper indicated and the -obtained result table and the expected one will both be displayed. +If any of the assertions of a story fails, it will be properly indicated and +the obtained result table and the expected one will both be displayed. ## Command: BQL The `bql` command starts a REPL that allows running BQL commands. The REPL can -provide basic help on usage as shown below. Currently the REPL has limited +provide basic help on usage as shown below. Currently, the REPL has limited support for terminal input. BQL statements need to be in a single line and there -is currently not support for cursor keys neither history of past BQL statements. +is currently no support for cursor keys or history of past BQL statements. ``` $ bw bql @@ -258,7 +259,7 @@ against the chosen backend. The benchmarks focus on performance of: 2. Removing triples from a graph. 3. BQL statements to bound backend performance. -All this benchmarks run against synthetic data using two graph generators: +All these benchmarks run against synthetic data using two graph generators: 1. _Tree graph generator_: Given an arbitrary branching factor it generates the requested number of triples by walking an imaginary tree in depth first @@ -270,20 +271,20 @@ All this benchmarks run against synthetic data using two graph generators: relates them together. The sampling of the nodes pair is done without replacement. -These two generators create graph with very different structural properties. +These two generators create graphs with very different structural properties. -All benchmarks consist on generating random triple sets using both generators -and using them as the graph to which to run the operations. Each benchmark is -run 10 times and the the average and standard deviation of the time spend to +All benchmarks consist of generating random triple sets using both generators +and using them as the graphs on which to run the operations. Each benchmark is +run 10 times and the the average and standard deviation of the time spent to run the operation is computed. Also, the benchmark runner computes an approximation of how many triples per second were processed. Each benchmark battery is run twice, sequentially and concurrently. The goal is -to also measure the impact of concurrent operations on the driver. Currently +to also measure the impact of concurrent operations on the driver. Currently, the command does not allow you to choose any of the parameters used. -Below there is an example of how to run the benchmarks against the default -in memory driver. +There is an example below of how to run the benchmarks against the default +in-memory driver. ``` $ bw --driver=VOLATILE benchmark diff --git a/docs/graph_serialization.md b/docs/graph_serialization.md index aef51e84..b8a3faf3 100644 --- a/docs/graph_serialization.md +++ b/docs/graph_serialization.md @@ -1,6 +1,6 @@ # Graph Marshaling/Unmarshaling -Graph can be marshaled to text or unmarshaled back from text into a graph +Graphs can be marshaled to text or unmarshaled back from text into a graph using the ```io``` package. The package provides two simple functions in [io](../io/io.go). diff --git a/docs/storage_abstraction_layer.md b/docs/storage_abstraction_layer.md index 056a9084..fa4add41 100644 --- a/docs/storage_abstraction_layer.md +++ b/docs/storage_abstraction_layer.md @@ -1,10 +1,11 @@ # Storage Abstraction Layer -BadWolf does not provide any storage. Instead provide a low level API for -data persistance. This allow to provide different storage implementations -(also known sometimes as drivers) but still maintain the same data abstractions -and data manipulation. This property allows you to use your favorite backend, -for data storage, or just implement a new one for your next project. +BadWolf does not provide any storage. Instead, it provide a low level API for +data persistence. This allows us to provide different storage implementations +(also known sometimes as drivers), but still maintain the same data +abstractions and data manipulation. This property allows you to use your +favorite backend for data storage, or just implement a new one for your next +project. BadWolf release comes along only with a simple volatile, RAM-based implementation of the storage abstraction layer to illustrate how the API can be implemented. @@ -18,9 +19,9 @@ The storage abstraction layer is built around two simple interfaces: query language. The goal of these interfaces is to allow writing specialized drivers for -different storage backends. For instance, BadWolf provides a simple memory -based implementation of this interfaces in the ```storage/memory``` package. -All relevant interface definitions can be found in the +different storage backends. For instance, BadWolf provides a simple +memory-based implementation of these interfaces in the ```storage/memory``` +package. All relevant interface definitions can be found in the [storage.go](../storage/storage.go) file of the ```storage``` package. Also ```storage/memory``` package provides a volatile memory-only implementation of both ```storage.Store``` and ```storage.Graph``` interfaces. diff --git a/docs/temporal_graph_modeling.md b/docs/temporal_graph_modeling.md index a2fdb841..ca899abe 100644 --- a/docs/temporal_graph_modeling.md +++ b/docs/temporal_graph_modeling.md @@ -35,8 +35,8 @@ types. wher == is the case sensitive equal. * _Covariant_: Given two types A and B, A [covariant](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) ) - B if B _is a_ A. In other word, A _covariant_ B if B is a prefix - of A. Or in other words, A could replace the usage of B and still + B if B _is a_ A. In other words, A _covariant_ B if B is a prefix + of A, or A could replace the usage of B and still convey a refined meaning. ### Node ID @@ -51,7 +51,7 @@ node IDs is that they cannot contain for efficient marshaling reasons neither Nodes can be marshaled and unmarshaled from a simple text representation. This representation follows this simple structure ```type``` for efficient -processing. Some example of marshaled into text nodes are listed below. +processing. Some examples of nodes marshaled into text are listed below. ``` /organization/country @@ -70,20 +70,20 @@ allowed to be boxed in a literal. These types are: * _Bool_ indicates that the type contained in the literal is a bool. * _Int64_ indicates that the type contained in the literal is an int64. * _Float64_ indicates that the type contained in the literal is a float64. -* _String_ indicates that the type contained in the literal is a string. +* _Text_ indicates that the type contained in the literal is a string. * _Blob_ indicates that the type contained in the literal is a []byte. It is important to note that a container contains one value, and one value only. Also, as mentioned earlier, all values and, hence, literals are immutable. _String_ and _Blob_ can contain elements of arbitrary length. This can be problematic depending on the storage backend being used. For that reason, -the ```literal``` package provides mechanisms to enforce maximum lenght limits +the ```literal``` package provides mechanisms to enforce maximum length limits to protect storage backends. Two literal builders are provided to create new literals: * _DefaultBuilder_ allows building valid literals of unbounded size. -* _NewBoundeBuilder_ allows building valid literals of a bounded specified size. +* _NewBoundedBuilder_ allows building valid literals of a bounded specified size. Literals can be pretty printed into a string format. The pretty printing retains the type and value of the literal. The format of the pretty printing formed @@ -119,15 +119,15 @@ kind of predicates: * _Immutable_ or predicates that are always valid regardless of when they were created. For instance, they are useful to describe properties that never change, for instance, the color of someone's eyes. -* _Temporal_ predicates that are anchored at some point along the time - continuum. For instance, the predicate _met_ describing when - two nodes met is anchored at a particular time. +* _Temporal_ predicates are anchored at some point along the time continuum. + For instance, the predicate _met_ describing when two nodes met + is anchored at a particular time. It is important to note here that temporal predicates are descriptive of a property in relation to time. The granularity (or window) of validity of that predicate is left to the temporal reasoning module. This is important, since -allow to reason against arbitrary time granularities. All time calculations -and reasoning in BadWold assume a Gregorian calendar. +it allows us to reason against arbitrary time granularities. All time +calculations and reasoning in BadWolf assume a Gregorian calendar. ### Predicate ID @@ -139,10 +139,10 @@ unmarshaling. ### Time anchors When parsing or printing dates into time anchors for temporal predicates, -Badwolf follows the [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) variant +BadWolf follows the [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) variant [RFC3339Nano](http://golang.org/pkg/time/#pkg-constants) as specified in the GO programming language to provide reliable granularity to express anchors in -nanoseconds. An example of time anchor express in RFC3339Nano format is shown +nanoseconds. An example of time anchor expressed in RFC3339Nano format is shown below. ``` @@ -168,13 +168,13 @@ The basic unit of storage on BadWolf is the triple. A triple is a three tuple Triples can be marshaled and unmarshaled. The string representation of a triple it is just the string representation of each of its components separated by -blank separator (tab is the prefered blank separator). +blank separator (tab is the preferred blank separator). ## Blank nodes and triple reification A blank node is a node of type ```/_``` where the id is unique in BadWolf. Blank nodes can requested to be created by BadWolf. The main use of blank nodes -is to allow triple reification, or predicate properies about facts. It is +is to allow triple reification, or predicate properties about facts. It is important to keep in mind that predication properties about a node can be achieved by a triple, however predicating properties about a fact (triple) require reification. This is better explained with an example. @@ -205,7 +205,7 @@ triple would add the following triples. Reifying temporal triples anchors all the derived temporal triples at the same time anchor of the original triple. Now, you can predicate any property about the fact by predicating against the blank node. Hence we can now - predicate about where John and Mery met as shown below. + predicate about where John and Mary met as shown below. ``` /user "met"@[2006-01-02T15:04:05.999999999Z07:00] /user @@ -215,6 +215,6 @@ triple would add the following triples. /_ "location"@[2006-01-02T15:04:05.999999999Z07:00] /city ``` -Anchoring the time predicate on the same time ancor as the reified triples +Anchoring the time predicate on the same time anchor as the reified triples seem appropriate for this example, but there are no restrictions of what you predicate against blank nodes.