<commit_before>;;;; This file is part of algebolic. Copyright (C) 2014-, <NAME>.
;;;;
;;;; Not for distribution.

(ns algebolic.expression.algebra
  "This namespace implements some basic computer algebra operations on algebolic expressions."
  (:require [algebolic.expression.core :as expression]
            [clojure.core.match :as match]
            [clojure.walk :as walk]
            [algebolic.expression.core :as expression]))

(defn- not-number?
  [x]
  (not (number? x)))

(defn expand
  [expr]
  (match/match [expr]
               ;; distribute plus through times
               [[:times a [:plus b c]]] [:plus [:times a b] [:times a c]]
               [[:times [:plus a b] c]] [:plus [:times a c] [:times b c]]
               [[:times a [:minus b c]]] [:minus [:times a b] [:times a c]]
               [[:times [:minus a b] c]] [:minus [:times a c] [:times b c]]
               ;; associative operations to the left
               [[:plus a [:plus b c]]] [:plus [:plus a b] c]
               [[:minus a [:minus b c]]] [:minus [:minus a b] c]
               [[:times a [:times b c]]] [:times [:times a b] c]
               ;; times to the right
               ;;[[:times [:times a b] c]] [:times a [:times b c]]
               ;;[[:plus [:plus a b] c]] [:plus a [:plus b c]]
               ;; always move numbers to the left
               [[:plus (a :guard not-number?) (b :guard number?)]] [:plus b a]
               [[:minus (a :guard not-number?) (b :guard number?)]] [:minus b a]
               [[:times (a :guard not-number?) (b :guard number?)]] [:times b a]
               ;; reduce arithmetic operations on numbers
               [[:plus (a :guard number?) (b :guard number?)]] (+ a b)
               [[:minus (a :guard number?) (b :guard number?)]] (- a b)
               [[:times (a :guard number?) (b :guard number?)]] (* a b)
               ;; reduce trig operations on numbers
               [[:cos (a :guard number?)]] (Math/cos a)
               [[:sin (a :guard number?)]] (Math/sin a)
               ;; leave everything else
               [x] x
               ))

(defn expand-tree
  [expr]
  (if (expression/non-terminal? expr)
    (expand (expression/make-expression (first expr) (map expand-tree (rest expr))))
    expr))

(defn expand-full
  [expr]
  (let [new-exp (expand-tree expr)]
    (if (= expr new-exp)
      new-exp
      (recur new-exp))))<commit_msg>Rearrange the CA functions a bit.<commit_after>;;;; This file is part of algebolic. Copyright (C) 2014-, <NAME>.
;;;;
;;;; Not for distribution.

(ns algebolic.expression.algebra
  "This namespace implements some basic computer algebra operations on algebolic expressions. And by 'basic'
  I really mean basic. The functions here make no attempt at being a complete computer algebra system, but
  rather offer a few useful transformations that can be used both in the EA, and also by hand for
  understanding expressions."
  (:require [algebolic.expression.core :as expression]
            [clojure.core.match :as match]
            [clojure.walk :as walk]
            [algebolic.expression.core :as expression]))

(defn- not-number?
  [x]
  (not (number? x)))


(defn- operate-tree
  "Takes an expression and applies the given operation to every sub-expression, including the
  expression itself."
  [op expr]
  (if (expression/non-terminal? expr)
    (op (expression/make-expression (first expr) (map (partial operate-tree op) (rest expr))))
    expr))

(defn- operate-full
  "Repeatedly applies the operation to the expression, and its sub-expressions, until the
  result no longer changes. Beware of infinte loops!"
  [op expr]
  (let [new-exp (operate-tree op expr)]
    (if (= expr new-exp)
      new-exp
      (recur op new-exp))))

(defn- expand-expr
  "Tries to expand an expression as much as possible, and transform it to a canonical form."
  [expr]
  (match/match [expr]
               ;; distribute plus and minus through times
               [[:times a [:plus b c]]] [:plus [:times a b] [:times a c]]
               [[:times [:plus a b] c]] [:plus [:times a c] [:times b c]]
               [[:times a [:minus b c]]] [:minus [:times a b] [:times a c]]
               [[:times [:minus a b] c]] [:minus [:times a c] [:times b c]]
               ;; associative operations to the left
               [[:plus a [:plus b c]]] [:plus [:plus a b] c]
               [[:minus a [:minus b c]]] [:minus [:minus a b] c]
               [[:times a [:times b c]]] [:times [:times a b] c]
               ;; always move numbers to the left
               [[:plus (a :guard not-number?) (b :guard number?)]] [:plus b a]
               [[:minus (a :guard not-number?) (b :guard number?)]] [:minus b a]
               [[:times (a :guard not-number?) (b :guard number?)]] [:times b a]
               ;; reduce arithmetic operations on numbers
               [[:plus (a :guard number?) (b :guard number?)]] (+ a b)
               [[:minus (a :guard number?) (b :guard number?)]] (- a b)
               [[:times (a :guard number?) (b :guard number?)]] (* a b)
               ;; reduce trig operations on numbers
               [[:cos (a :guard number?)]] (Math/cos a)
               [[:sin (a :guard number?)]] (Math/sin a)
               ;; leave everything else
               [x] x
               ))

(defn expand-full
  "Tries to expand an expression as much as possible, and transform it to a canonical form."
  [expr]
  (operate-full expand-expr expr))
{'fraction_non_alphanumeric': 0.14965986394557823, 'fraction_numerical': 0.0014708586137157566, 'mean_word_length': 2.190615835777126, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6596336', 'n_tokens_mistral': 1711, 'n_tokens_neox': 1650, 'n_words': 663}