Skip to content

Commit 2879c5b

Browse files
author
Paula Gearon
committed
Merge branch 'master' of github.com:threatgrid/naga into issue-42
2 parents bba9652 + 4761f41 commit 2879c5b

File tree

21 files changed

+462
-120
lines changed

21 files changed

+462
-120
lines changed

.travis.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
11
language: clojure
2+
3+
install:
4+
- lein deps
5+
6+
script:
7+
- lein kibit
8+
- lein test
9+
10+
notifications:
11+
email:
12+
on_success: change
13+
on_failure: change

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ This may eventually be split out into its own project.
114114

115115
## License
116116

117-
Copyright © 2016 Cisco Systems
117+
Copyright © 2016-2017 Cisco Systems
118118

119119
Copyright © 2011-2016 Paula Gearon
120120

doc/NagaFramework.png

139 KB
Loading

project.clj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@
1010
[the/parsatron "0.0.7"]
1111
[cheshire "5.6.3"]
1212
[com.datomic/datomic-free "0.9.5544"]]
13+
:profiles {:dev {:plugins [[lein-kibit "0.1.3"]]}}
1314
:main naga.cli)

src/naga/cli.clj

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,15 @@
3333

3434
(defn usage
3535
[{summary :summary}]
36-
(->> ["Executes Naga on a program."
37-
""
38-
"Usage: naga [filename]"
39-
""
40-
summary
41-
(str "Store types: " (into [] stores))
42-
""]
43-
(string/join \newline)))
36+
(string/join
37+
\newline
38+
["Executes Naga on a program."
39+
""
40+
"Usage: naga [filename]"
41+
""
42+
summary
43+
(str "Store types: " (vec stores))
44+
""]))
4445

4546
(defn run-all
4647
"Runs a program, and returns the data processed, the results, and the stats.
@@ -74,7 +75,6 @@
7475
:output (remove (set axioms) data)
7576
:stats stats}))
7677

77-
7878
(defn- nm
7979
"Returns a string version of a keyword. These are not being represented
8080
as Clojure keywords, so namespaces (when they exist) are separated by
@@ -84,7 +84,6 @@
8484
(str n ":" (name k))
8585
(name k)))
8686

87-
8887
(defn- predicate-string
8988
"Convert a predicate triplet into a string."
9089
[[e p v]]
@@ -95,7 +94,7 @@
9594
(defn logic-program
9695
[in-stream]
9796
(let [{:keys [input output stats]} (run-all in-stream)]
98-
(println "INPUT DATA")
97+
(println "INPUT DATA")
9998
(doseq [a input] (println (predicate-string a)))
10099
(println "\nNEW DATA")
101100
(doseq [a output] (println (predicate-string a)))))

src/naga/data.clj

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
[k (into {} (map #(apply vector (rest %)) vs))]))
2323
(into {}))
2424
node-list (loop [nl [] n node]
25-
(if (= :naga/nil n)
25+
(if-not n
2626
nl
2727
(let [{f :naga/first r :naga/rest} (listmap n)]
2828
(recur (conj nl f) r))))]
@@ -44,11 +44,10 @@
4444
(let [id (store/new-node *current-storage*)
4545
[value-id triples] (value-triples v)
4646
[next-id next-triples] (list-triples vs)]
47-
[id (concat [[id (store/data-property *current-storage* value-id) value-id]
48-
[id :naga/rest next-id]]
47+
[id (concat [[id (store/data-property *current-storage* value-id) value-id]]
48+
(when next-id [[id :naga/rest next-id]])
4949
triples
50-
next-triples)])
51-
[:naga/nil nil]))
50+
next-triples)])))
5251

5352
(defmethod value-triples List
5453
[vlist]
@@ -59,7 +58,7 @@
5958

6059
(defmethod value-triples Map [v] (map->triples v))
6160

62-
(defmethod value-triples nil [v] [:naga/nil nil])
61+
(defmethod value-triples nil [v] nil)
6362

6463
(defmethod value-triples :default [v] [v nil])
6564

@@ -69,7 +68,7 @@
6968
and builds triples around it"
7069
[entity-id :- s/Any
7170
[property value] :- [s/Keyword s/Any]]
72-
(let [[value-id value-data] (value-triples value)]
71+
(if-let [[value-id value-data] (value-triples value)]
7372
(cons [entity-id property value-id] value-data)))
7473

7574

@@ -103,8 +102,7 @@
103102
"Converts parsed JSON into a sequence of triples for a provided storage."
104103
[storage j]
105104
(binding [*current-storage* storage]
106-
(doall (apply concat
107-
(map ident-map->triples j)))))
105+
(doall (mapcat ident-map->triples j))))
108106

109107

110108
(s/defn stream->triples :- [Triple]
@@ -129,8 +127,7 @@
129127
"Return all the property/value pairs for a given entity in the store."
130128
[store :- Storage
131129
entity :- s/Any]
132-
(if-not (= entity :naga/nil)
133-
(store/resolve-pattern store [entity '?p '?o])))
130+
(store/resolve-pattern store [entity '?p '?o]))
134131

135132

136133
(s/defn check-structure :- (s/maybe [[s/Keyword s/Any]])
@@ -162,8 +159,9 @@
162159
;; convert the data to a map
163160
(let [st (into {} pairs)]
164161
;; if the properties indicate a list, then process it
165-
(if-let [remaining (:naga/rest st)]
166-
(let [first-prop-elt (get-data st)
162+
(when (:naga/first st)
163+
(let [remaining (:naga/rest st)
164+
first-prop-elt (get-data st)
167165
[_ first-elt] (recurse-node store first-prop-elt)]
168166
(assert first-elt)
169167
;; recursively build the list
@@ -184,11 +182,12 @@
184182
"Uses a set of property-value pairs to load up a nested data structure from the graph"
185183
[store :- Storage
186184
prop-vals :- [[s/Keyword s/Any]]]
187-
(->
185+
(dissoc
188186
(->> prop-vals
189187
(map (partial recurse-node store))
190188
(into {}))
191-
(dissoc :db/id :db/ident)))
189+
:db/id
190+
:db/ident))
192191

193192

194193
(s/defn id->json :- {s/Keyword s/Any}

src/naga/engine.clj

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,16 @@
9393
;; the rule was run
9494
[storage
9595
(u/mapmap :name (comp deref :execution-count) (vals rules))]
96-
96+
9797

9898
;; find if any patterns have updated
9999
(if-let [dirty-patterns (seq (keep extract-dirty-pattern
100100
status))]
101101
;; rule needs to be run
102102
(let [counted-patterns (keep (partial resolve-count storage status)
103-
dirty-patterns)
103+
dirty-patterns)
104104

105-
counted-set (into #{} counted-patterns)
105+
counted-set (set counted-patterns)
106106

107107
hinted-patterns (map #(get counted-set % %) body)]
108108

@@ -142,7 +142,6 @@
142142
{:keys [rules axioms]} :- Program]
143143
(let [storage (store/get-storage-handle config)
144144
storage' (store/start-tx storage)
145-
[output-storage stats] (->> (store/assert-data storage' axioms)
146-
(execute rules))
145+
[output-storage stats] (execute rules (store/assert-data storage' axioms))
147146
result-storage (store/commit-tx output-storage)]
148147
[result-storage stats]))

src/naga/lang/basic.clj

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[the.parsatron :refer :all]
77
[naga.schema.structs :as st]))
88

9-
(defn choice*
9+
(defn choice*
1010
"choice with backtracking."
1111
[& args]
1212
(apply choice (map attempt args)))
@@ -60,7 +60,7 @@
6060

6161
;; This does not include all legal characters.
6262
;; Consider some others in future, especially >
63-
(def ns-word (many1 (choice (letter) (char \_) (char \-) (char \:))))
63+
(def ns-word (many1 (choice (letter) (digit) (char \_) (char \-) (char \:))))
6464

6565
(def word (many1 (letter)))
6666

@@ -73,48 +73,49 @@
7373

7474
(defparser integer []
7575
(let->> [i (either digits (signed-digits))]
76-
(always (Long/parseLong (apply str i)))))
76+
(always (Long/parseLong (str/join i)))))
7777

7878
(defparser floating-point []
7979
(let->> [i (either digits (signed-digits))
8080
f (>> (char \.) (many1 (digit)))]
81-
(always (Double/parseDouble (apply str (apply str i) \. f)))))
81+
(always (Double/parseDouble (apply str (str/join i) \. f)))))
8282

8383
(def number (either* (floating-point) (integer)))
8484

8585
;; parses strings of the form: 'it''s a string!'
8686
(defparser pstring1 []
87-
(let->> [s (many1 (between (char \') (char \') (many non-squote))) ]
88-
(always (apply str (flatten (interpose \' s))))))
87+
(let->> [s (many1 (between (char \') (char \') (many non-squote)))]
88+
(always (str/join (flatten (interpose \' s))))))
8989

9090
;; parses strings of the form: "She said, ""Hello,"" to me."
9191
(defparser pstring2 []
9292
(let->> [s (many1 (between (char \") (char \") (many non-dquote)))]
93-
(always (apply str (flatten (interpose \" s))))))
93+
(always (str/join (flatten (interpose \" s))))))
9494

9595
(def pstring (either (pstring1) (pstring2)))
9696

9797
;; variables start with a capital. Internally they start with ?
9898
(defparser variable []
9999
(let->> [f (upper-case-letter)
100-
r (many (letter))]
101-
(always (symbol (apply str "?" (Character/toLowerCase f) r) ))))
100+
r (many (choice (letter) (digit) (char \_) (char \-)))]
101+
(always (symbol (apply str "?" (Character/toLowerCase f) r)))))
102102

103103
(defn build-keyword
104104
"Creates a keyword from a parsed word token"
105105
[wrd]
106106
(let [[kns kname :as w] (str/split wrd #":")
107107
parts (count w)]
108108
;; use cond without a default to return nil
109-
(cond (= 2 parts) (cond (empty? kns) (keyword kname)
109+
(cond (Character/isDigit (first wrd)) nil
110+
(= 2 parts) (cond (empty? kns) (keyword kname)
110111
(seq kname) (keyword kns kname))
111112
(= 1 parts) (if-not (str/ends-with? wrd ":")
112113
(keyword kns)))))
113114

114115
;; atomic values, like a predicate, are represented as a keyword
115116
(defparser kw []
116117
(let->> [r ns-word]
117-
(let [wrd (apply str r)]
118+
(let [wrd (str/join r)]
118119
(if-let [k (build-keyword wrd)]
119120
(always k)
120121
(throw (fail (str "Invalid identifier: " wrd)))))))

src/naga/lang/pabu.clj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,16 @@ Parses code and returns Naga rules."
6767

6868
(def RuleAST
6969
{:type (s/eq :rule)
70-
:head [(s/one VK "property")
71-
(s/one Args "arguments")]
70+
:head [[(s/one VK "property")
71+
(s/one Args "arguments")]]
7272
:body [Predicate]})
7373

7474
(s/defn ast->rule :- Rule
7575
"Converts the rule structure returned from the parser"
7676
[{:keys [head body] :as rule-ast} :- RuleAST]
77-
(r/rule (triplet head)
77+
(r/rule (map triplet head)
7878
(mapcat structure body)
79-
(-> head first name gensym name)))
79+
(-> head ffirst name gensym name)))
8080

8181
(s/defn read-str :- {:rules [Rule]
8282
:axioms [Axiom]}

src/naga/lang/parser.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747

4848
;; a clause with a rule
4949
(defparser nonbase-clause []
50-
(let->> [head (>> opt-whitespace (structure))
50+
(let->> [head (>> opt-whitespace (structures))
5151
_ (>> opt-whitespace (string ":-") opt-whitespace)
5252
body (structures)
5353
_ (>> opt-whitespace (char \.) opt-whitespace)]

0 commit comments

Comments
 (0)