<commit_before>(ns signet.graph
  (:require [clojure.set :refer [difference]]
            [aprint.core :refer [aprint]]))

(def test-cg
  {:causal-order {10 []
                  20 [10]
                  30 [20]
                  40 [20]
                  50 [40]
                  60 [30 50]
                  70 [60]
                  80 [30]
                  90 [80]
                  100 [70]
                  110 [100]
                  120 [50]}
   :branches {"master" 110
              "fix" 120
              "dev" 90}})


(defn link-order [c causal-order heads]
  (loop [parents (get causal-order c)
         node c
         order (list [c])]
    (if (empty? parents)
      order
      (if (< 2 (count parents))
        (recur (get causal-order  (first parents))
               (first parents)
               (conj order [(first parents) node ]))
        (let [next-node (first (remove heads parents))]
          (recur (get causal-order next-node)
                 next-node
                 (conj order [next-node node ])))))))


(defn commit-graph->links [cg]
  (let [{:keys [branches causal-order]} cg
        heads (into #{} (vals branches))]
    (loop [[b c] (first branches)
           b-list (rest branches)
           result []]
      (if-not b
        (sort-by second #(> (count %1) (count %2)) result)
        (recur (first b-list)
               (rest b-list)
               (conj result [b (link-order c causal-order heads)]))))))

(defn distinct-links [g]
  (loop [[b l-order] (first g)
         b-list (rest g)
         links []]
    (if (empty? b-list)
      (into {} (conj links [b l-order]))
      (let [branch-diffs (map (fn [[k v]] [k (difference (set v) (set l-order))]) b-list)]
        (recur
         (first branch-diffs)
         (rest branch-diffs)
         (conj links [b (set l-order)]))))))


(defn distinct-nodes [g]
  (into {} (map (fn [[k v]] [k (mapv first v)]) g)))



(defn commit-graph->order [cg]
  (let [g (commit-graph->links cg)
        links (distinct-links g)]
    {:nodes (distinct-nodes g)
     :links links
     :x-order (map first links)
     :y-order (loop [old (map first links)
                     new (list)
                     i false]
                (if (empty? old)
                  new
                  (recur (rest old)
                         (if i
                           (concat new (list (first old)))
                           (concat (list (first old)) new))
                         (not i))))}))<commit_msg>more thoughts on graph algorithm<commit_after>(ns signet.graph
  (:require [clojure.set :refer [difference]]
            [aprint.core :refer [aprint]]))


(defmacro filter-map [bindings pred m]
  `(select-keys ~m
                (for [~bindings ~m
                      :when ~pred]
                  ~(first bindings))))


(defn branches->nodes [c causal-order heads]
  (loop [parents (get causal-order c)
         node c
         order (list c)]
    (if (nil? parents)
      order
      (if (< 2 (count parents))
        (recur (get causal-order  (first parents))
               (first parents)
               (conj order node))
        (let [next-node (first (remove heads parents))]
          (recur (get causal-order next-node)
                 next-node
                 (conj order next-node)))))))


(defn distinct-nodes [{:keys [nodes] :as cg}]
  (assoc cg
    :nodes
    (loop [[b l-order] (first nodes)
           b-list (rest nodes)
           links []]
      (if (empty? b-list)
        (into {} (conj links [b l-order]))
        (let [branch-diffs (map (fn [[k v]] [k (difference (set v) (set l-order))]) b-list)]
          (recur
           (first branch-diffs)
           (rest branch-diffs)
           (conj links [b (set l-order)])))))))


(defn commit-graph->nodes [cg]
  (let [{:keys [branches causal-order]} cg
        heads (into #{} (vals branches))]
    (assoc cg :nodes
           (loop [[b c] (first branches)
                  b-list (rest branches)
                  result []]
             (if-not b
               (sort-by second #(> (count %1) (count %2)) result)
               (recur (first b-list)
                      (rest b-list)
                      (conj result [b (branches->nodes c causal-order heads)])))))))

(defn nodes->order
  "doc-string"
  [{:keys [nodes causal-order branches] :as cg}]
  (let [new-nodes (map
                   (fn [[b b-nodes]]
                     [b (branches->nodes
                         (get branches b)
                         (select-keys causal-order b-nodes)
                         (into #{} (vals branches)))])
                   nodes)]
    (assoc cg
      :nodes
      (->> new-nodes
           (map (fn [[k v]] [k (rest v)]))
           (into {}))
      :branch-points
      (->> new-nodes
           (map (fn [[k v]] [k (first v)]))
           (into {})))))




(comment

  (def test-cg
    {:causal-order {10 []
                    20 [10]
                    30 [20]
                    40 [20]
                    50 [40]
                    60 [30 50]
                    70 [60]
                    80 [30]
                    90 [80]
                    100 [70]
                    110 [100]
                    120 [90]}
     :branches {"master" 110
                "fix" 50
                "dev" 120}})


  (let [{:keys [causal-order branches]} (->> test-cg
                                             commit-graph->nodes
                                             distinct-nodes
                                             nodes->order)
        branch-heads (into {} (map (fn [[k v]] [v k]) branches))]
    (map
     (fn [[k v]]
       [k ()])
     (filter-map [key val] (> (count val) 1) causal-order)))



  )
{'fraction_non_alphanumeric': 0.1423562412342216, 'fraction_numerical': 0.02226507713884993, 'mean_word_length': 1.2549407114624507, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4500751', 'n_tokens_mistral': 1849, 'n_tokens_neox': 1682, 'n_words': 521}