├── docs
├── _config.yml
├── img
│ └── Modules.png
├── index.md
├── Makefile
└── api
│ └── css
│ └── highlight.css
├── .projectile
├── test
├── classifier.bin
├── config_classifier2b.edn
├── config_classifier1.edn
├── config_classifier2.edn
└── config_tool.edn
├── circle.yml
├── bin
├── add-new-language.sh
├── clj2edn.sh
├── convert-rules.clj
└── convert-corpus.clj
├── dev
├── src
│ ├── user.clj
│ └── dev.clj
└── resources
│ └── dev.edn
├── src
└── clj_duckling
│ ├── dims
│ ├── quantity.clj
│ ├── number.clj
│ ├── volume.clj
│ ├── distance.clj
│ ├── temperature.clj
│ ├── core.clj
│ ├── money.clj
│ └── duration.clj
│ ├── engine
│ └── core.clj
│ ├── system.clj
│ └── util
│ └── helpers.clj
├── resources
└── languages
│ ├── ro
│ ├── corpus
│ │ ├── duration.edn
│ │ ├── budget.edn
│ │ ├── order.edn
│ │ ├── temperature.edn
│ │ ├── gender.edn
│ │ ├── communication.edn
│ │ ├── finance.edn
│ │ ├── time.edn
│ │ └── measure.edn
│ └── rules
│ │ ├── order.edn
│ │ ├── gender.edn
│ │ ├── budget.edn
│ │ ├── temperature.edn
│ │ └── communication.edn
│ ├── ga
│ ├── corpus
│ │ ├── number.edn
│ │ ├── numbers.edn
│ │ ├── temperature.edn
│ │ ├── measure.edn
│ │ ├── time.edn
│ │ └── finance.edn
│ └── rules
│ │ ├── temperature.edn
│ │ ├── duration.edn
│ │ └── finance.edn
│ ├── ja
│ ├── corpus
│ │ ├── temperature.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── rules
│ │ ├── temperature.edn
│ │ ├── duration.edn
│ │ └── cycle.edn
│ ├── ko
│ ├── corpus
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ ├── finance.edn
│ │ └── measure.edn
│ └── rules
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ └── finance.edn
│ ├── zh
│ ├── corpus
│ │ ├── temperature.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── rules
│ │ ├── temperature.edn
│ │ ├── duration.edn
│ │ └── cycle.edn
│ ├── en
│ ├── corpus
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ ├── finance.edn
│ │ ├── measure.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── rules
│ │ ├── temperature.edn
│ │ └── communication.edn
│ ├── hr
│ ├── corpus
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ ├── measure.edn
│ │ ├── finance.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── rules
│ │ ├── temperature.edn
│ │ └── communication.edn
│ ├── et
│ ├── corpus
│ │ ├── _temperature.edn
│ │ ├── _communication.edn
│ │ ├── _finance.edn
│ │ ├── _measure.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── rules
│ │ ├── _temperature.edn
│ │ ├── _communication.edn
│ │ └── _finance.edn
│ ├── pt
│ ├── corpus
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ ├── finance.edn
│ │ └── measure.edn
│ └── rules
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ ├── duration.edn
│ │ └── finance.edn
│ ├── es
│ ├── corpus
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ ├── finance.edn
│ │ ├── measure.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── rules
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ ├── duration.edn
│ │ └── finance.edn
│ ├── fr
│ ├── corpus
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ ├── finance.edn
│ │ ├── measure.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── rules
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ └── finance.edn
│ ├── it
│ ├── rules
│ │ ├── temperature.edn
│ │ ├── communication.edn
│ │ └── duration.edn
│ └── corpus
│ │ ├── communication.edn
│ │ └── temperature.edn
│ ├── my
│ ├── corpus
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── rules
│ │ └── number.edn
│ ├── id
│ ├── corpus
│ │ ├── finance.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── rules
│ │ └── finance.edn
│ ├── nl
│ ├── corpus
│ │ ├── measure.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── rules
│ │ └── cycle.edn
│ ├── nb
│ └── corpus
│ │ ├── finance.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ ├── sv
│ └── corpus
│ │ ├── finance.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ ├── he
│ └── corpus
│ │ ├── number.edn
│ │ └── numbers.edn
│ ├── da
│ └── corpus
│ │ ├── number.edn
│ │ └── numbers.edn
│ ├── vi
│ └── corpus
│ │ ├── finance.edn
│ │ ├── number.edn
│ │ └── numbers.edn
│ ├── ar
│ └── corpus
│ │ ├── number.edn
│ │ └── numbers.edn
│ └── pl
│ └── corpus
│ ├── number.edn
│ └── numbers.edn
├── .gitignore
├── README.org
├── LICENSE
├── PATENTS
├── .build.el
└── project.clj
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/.projectile:
--------------------------------------------------------------------------------
1 | -/logs
2 | -/docs/api
3 | -.git/
4 | -/target
--------------------------------------------------------------------------------
/docs/img/Modules.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpom/clj-duckling/HEAD/docs/img/Modules.png
--------------------------------------------------------------------------------
/test/classifier.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpom/clj-duckling/HEAD/test/classifier.bin
--------------------------------------------------------------------------------
/circle.yml:
--------------------------------------------------------------------------------
1 | deployment:
2 | master:
3 | branch: master
4 | commands:
5 | - lein deploy private
--------------------------------------------------------------------------------
/bin/add-new-language.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | p="$(dirname "$0")/../resources/languages"
4 | l=$p/$1
5 | mkdir "$l"
6 | mkdir "$l/corpus"
7 | mkdir "$l/rules"
8 |
--------------------------------------------------------------------------------
/dev/src/user.clj:
--------------------------------------------------------------------------------
1 | (ns user)
2 |
3 | (defn dev
4 | "Load and switch to the 'dev' namespace."
5 | []
6 | (require 'dev)
7 | (in-ns 'dev)
8 | :loaded)
9 |
--------------------------------------------------------------------------------
/src/clj_duckling/dims/quantity.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.dims.quantity
2 | (:require
3 | [clj-duckling.util.engine :refer [export-value]]))
4 |
5 | (defmethod export-value :quantity [token _]
6 | (select-keys token [:value :unit :product]))
7 |
--------------------------------------------------------------------------------
/src/clj_duckling/dims/number.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.dims.number
2 | (:require
3 | [clj-duckling.util.engine :refer [export-value]]))
4 |
5 | (defmethod export-value :number [{:keys [value unit] :as token} _]
6 | {:type "value" :value value :unit unit})
7 |
--------------------------------------------------------------------------------
/src/clj_duckling/dims/volume.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.dims.volume
2 | (:require
3 | [clj-duckling.util.engine :refer [export-value]]))
4 |
5 | (defmethod export-value :volume [{:keys [value unit] :as token} _]
6 | {:type "value" :value value :unit unit})
7 |
--------------------------------------------------------------------------------
/src/clj_duckling/dims/distance.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.dims.distance
2 | (:require
3 | [clj-duckling.util.engine :refer [export-value]]))
4 |
5 | (defmethod export-value :distance [{:keys [value unit] :as token} _]
6 | {:type "value" :value value :unit unit})
7 |
--------------------------------------------------------------------------------
/src/clj_duckling/dims/temperature.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.dims.temperature
2 | (:require
3 | [clj-duckling.util.engine :refer [export-value]]))
4 |
5 | (defmethod export-value :temperature [{:keys [value unit] :as token} _]
6 | {:type "value" :value value :unit unit})
7 |
--------------------------------------------------------------------------------
/bin/clj2edn.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | # parameter: directorul
3 | for i in resources/languages/*;
4 | # do echo $i/rules;
5 | # do bin/convert-rules.clj $i/rules;
6 | # do bin/convert-corpus.clj $i/corpus;
7 | # do rm $i/corpus/*.clj;
8 | do rm $i/rules/*.clj;
9 | done
10 |
--------------------------------------------------------------------------------
/resources/languages/ro/corpus/duration.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["5 ani"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :duration (:dim token)) (= {:year 5 :value 5 :unit :year :normalized {:value 157766400, :unit \"second\"}} (:value token))))"]}]}
5 |
--------------------------------------------------------------------------------
/resources/languages/ro/corpus/budget.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["sub 300 lei" "sub 300 de lei" "maxim 300 lei"]
4 | :checks [#clj-duckling/corpus "(budget 300 \"RON\" :max)"]}
5 | {:text ["peste 100 lei" "minim 100 lei"]
6 | :checks [#clj-duckling/corpus "(budget 100 \"RON\" :min)"]}]}
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: clj-duckling
3 | description: A Clojure library that parses text into structured data.
4 | ---
5 |
{{ title }}
6 | {{ description }}
7 |
8 |
9 | User Guide
10 |
11 | Developer Guide
12 |
13 | API
14 |
--------------------------------------------------------------------------------
/resources/languages/ga/corpus/number.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "a náid"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "aon" "a haon" "amháin"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["20" "fiche"]
8 | :checks [#clj-duckling/corpus "(number 20)"]}]}
--------------------------------------------------------------------------------
/resources/languages/ga/corpus/numbers.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "a náid"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "aon" "a haon" "amháin"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["20" "fiche"]
8 | :checks [#clj-duckling/corpus "(number 20)"]}]}
--------------------------------------------------------------------------------
/resources/languages/ro/corpus/order.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["ultima comanda"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :order (:dim token)) (= -1 (:value token))))"]}
5 | {:text ["comanda 123456789"]
6 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :order (:dim token)) (= 123456789 (:value token))))"]}]}
--------------------------------------------------------------------------------
/src/clj_duckling/dims/core.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.dims.core
2 | (:require
3 | [clj-duckling.dims.distance]
4 | [clj-duckling.dims.duration]
5 | [clj-duckling.dims.money]
6 | [clj-duckling.dims.number]
7 | [clj-duckling.dims.quantity]
8 | [clj-duckling.dims.temperature]
9 | [clj-duckling.dims.time]
10 | [clj-duckling.dims.volume]))
11 |
12 |
--------------------------------------------------------------------------------
/src/clj_duckling/engine/core.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.engine.core
2 | "Engine common protocol and specs"
3 | (:require
4 | [clojure.spec.alpha :as s]
5 | [nlpcore.protocols :as core]
6 | ))
7 |
8 | (defprotocol Engine
9 | (load-rules! [this] "Load rules")
10 | (get-rules [this] "Get rules"))
11 |
12 |
13 | (s/def :engine/rules #(and (satisfies? core/Module %) (satisfies? Engine %)))
14 |
--------------------------------------------------------------------------------
/resources/languages/ja/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "摂氏37°" "摂氏37度"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"celsius\")"]}
5 | {:text ["70°F" "華氏70°" "華氏70度"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"fahrenheit\")"]}
7 | {:text ["45°" "45度"]
8 | :checks [#clj-duckling/corpus "(temperature 45 \"degree\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/ko/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "섭씨37°" "섭씨37도"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"celsius\")"]}
5 | {:text ["70°F" "화씨70°" "화씨70도"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"fahrenheit\")"]}
7 | {:text ["45°" "45도"]
8 | :checks [#clj-duckling/corpus "(temperature 45 \"degree\")"]}]}
--------------------------------------------------------------------------------
/src/clj_duckling/dims/money.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.dims.money
2 | (:require
3 | [clj-duckling.util.engine :refer [export-value]]))
4 |
5 | (defmethod export-value :amount-of-money [{:keys [value unit] :as token} _]
6 | {:type "value" :value value :unit unit})
7 |
8 | (defmethod export-value :budget [{:keys [value unit level] :as token} _]
9 | {:type "value" :value value :unit unit :level level})
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .lein-repl-history
3 | .lein-failures
4 | .nrepl-port
5 | duckling.iml
6 | pom.xml
7 | pom.xml.asc
8 | target
9 | .idea
10 | resources/export.json
11 | /.lein-codeindex
12 | /TAGS
13 | /GPATH
14 | /GRTAGS
15 | /GSYMS
16 | /GTAGS
17 | /.lein-env
18 | dev/resources/local.edn
19 | dev/src/local.clj
20 | /logs
21 | /tmp.edn
22 | /tmp
23 | /err.log
24 | /test/ro_model.bin
25 | /test/tmp.bin
26 |
--------------------------------------------------------------------------------
/resources/languages/ro/rules/order.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "last order"
2 | :pattern "#\"(?i)ultima( mea)? comand[aă]\""
3 | :production "{:dim :order, :value -1}"}
4 | #clj-duckling.engine/rule {:name "order"
5 | :pattern "[#\"(?i)comand[aă]\" (integer 0)]"
6 | :production "{:dim :order, :value (:value %2)}"}]
7 |
--------------------------------------------------------------------------------
/resources/languages/ro/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "37 ° celsius" "37 grade Celsius" "treizeci si sapte celsius"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"celsius\")"]}
5 | {:text ["70°F" "70 ° Fahrenheit" "70 grade F" "saptezeci Fahrenheit"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"fahrenheit\")"]}
7 | {:text ["45°" "45 grade"]
8 | :checks [#clj-duckling/corpus "(temperature 45 \"degree\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/zh/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "摄氏37°" "攝氏37°" "摄氏37度" "攝氏37度" "37摄氏°" "37攝氏°" "37摄氏度" "37攝氏度"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"celsius\")"]}
5 | {:text ["70°F" "华氏70°" "華氏70°" "华氏70度" "華氏70度" "70华氏°" "70華氏°" "70华氏度" "70華氏度"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"fahrenheit\")"]}
7 | {:text ["45°" "45度"]
8 | :checks [#clj-duckling/corpus "(temperature 45 \"degree\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/ro/corpus/gender.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["barbat" "bărbat" "baiat" "baietel" "băiat" "băieţel" "sot" "soţ" "fiu" "frate" "fecior" "tata" "bunic"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :gender (:dim token)) (= :male (:value token))))"]}
5 | {:text ["femeie" "muiere" "sotie" "soţie" "fica" "fetita" "fetiţa" "mama" "bunica"]
6 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :gender (:dim token)) (= :female (:value token))))"]}]}
--------------------------------------------------------------------------------
/resources/languages/ro/rules/gender.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "male",
2 | :pattern "#\"(?i)b[aă]rba[tţ]i?|b[aă]i[ae][tţ](i|el)?|so[tţ]i?|fiu|frate|fra[tţ]i?|feciori?|tat[aă]|bunic\"",
3 | :production "{:dim :gender, :value :male}"}
4 | #clj-duckling.engine/rule {:name "female",
5 | :pattern "#\"(?i)femeie|feti[tţ][aăe]|muiere|so[tţ]i[ie]|fica|mam[aă]|bunic[aă]\"",
6 | :production "{:dim :gender, :value :female}"}]
7 |
--------------------------------------------------------------------------------
/resources/languages/en/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "37 ° celsius" "37 degrees Celsius" "thirty seven celsius" "37 degrees Celsius" "thirty seven celsius"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"celsius\")"]}
5 | {:text ["70°F" "70 ° Fahrenheit" "70 degrees F" "seventy Fahrenheit"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"fahrenheit\")"]}
7 | {:text ["45°" "45 degrees" "45 deg."]
8 | :checks [#clj-duckling/corpus "(temperature 45 \"degree\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/ro/rules/budget.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "max budget",
2 | :pattern "[#\"(?i)sub|max(\\.|im)?\" (dim :amount-of-money)]",
3 | :production "{:dim :budget, :value (:value %2), :unit (:unit %2), :level :max}"}
4 | #clj-duckling.engine/rule {:name "min budget",
5 | :pattern "[#\"(?i)peste|min(\\.|im)?\" (dim :amount-of-money)]",
6 | :production "{:dim :budget, :value (:value %2), :unit (:unit %2), :level :min}"}]
7 |
--------------------------------------------------------------------------------
/resources/languages/hr/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "37 ° celzija" "37 stupnjeva Celzija" "trideset i sedam celzija" "37 stupnjeva Celzija" "trideset sedam celzija"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"celsius\")"]}
5 | {:text ["70°F" "70 ° Fahrenheit" "70 stupnjeva F" "sedamdeset Fahrenheit"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"fahrenheit\")"]}
7 | {:text ["45°" "45 stupnjeva" "45 deg."]
8 | :checks [#clj-duckling/corpus "(temperature 45 \"degree\")"]}]}
--------------------------------------------------------------------------------
/test/config_classifier2b.edn:
--------------------------------------------------------------------------------
1 | {
2 | :clj-duckling.model/classifier {:id "test-classifier"
3 | :language "ro"
4 | :binfile "test/tmp.bin"
5 | :loadbin? true
6 | :logger #ig/ref :duct.logger/timbre}
7 |
8 | :duct.logger/timbre {:level :error
9 | :set-root-config? true
10 | :appenders {:duct.logger.timbre/brief #ig/ref :duct.logger.timbre/brief}},
11 |
12 |
13 | :duct.logger.timbre/brief {:min-level :report},
14 | }
15 |
--------------------------------------------------------------------------------
/resources/languages/et/corpus/_temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "37° celsiuse kraadi" "37 kraadi Celsiuse järgi" "kolmkümmend seitse celsiust" "37 kraadi celsiust" "37 kraadi C" "kolmkümmend seitse kraadi celsiuse skaalal"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"celsius\")"]}
5 | {:text ["70°F" "70° Fahrenheiti kraadi" "70 kraadi F" "seitsekümmend Fahrenheiti"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"fahrenheit\")"]}
7 | {:text ["45°" "45 kraadi"]
8 | :checks [#clj-duckling/corpus "(temperature 45 \"degree\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/pt/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "37 ° celsius" "37 graus Celsius" "37 graus C" "trinta e sete celsius" "37 centígrados" "37 graus centigrados"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"C\")"]}
5 | {:text ["70°F" "70 ° Fahrenheit" "70 graus F" "setenta Fahrenheit"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"F\")"]}
7 | {:text ["45°" "45 graus"]
8 | :checks [#clj-duckling/corpus "(temperature 45)"]}
9 | {:text ["-10°" "- dez graus" "10 abaixo de zero"]
10 | :checks [#clj-duckling/corpus "(temperature -10)"]}]}
--------------------------------------------------------------------------------
/resources/languages/es/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "37 ° celsius" "37 grados Celsius" "37 grados C" "treinta y siete celsius" "37 centígrados" "37 grados centígrados"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"C\")"]}
5 | {:text ["70°F" "70 ° Fahrenheit" "70 grados F" "setenta Fahrenheit"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"F\")"]}
7 | {:text ["45°" "45 grados"]
8 | :checks [#clj-duckling/corpus "(temperature 45)"]}
9 | {:text ["-10°" "- diez grados" "10 bajo cero"]
10 | :checks [#clj-duckling/corpus "(temperature -10)"]}]}
--------------------------------------------------------------------------------
/resources/languages/ga/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "37 ° celsius" "37 céimeanna Celsius" "37 céimeanna C" "37 céimeanna ceinteagrád"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"celsius\")"]}
5 | {:text ["70°F" "70 ° Fahrenheit" "70 céimeanna F"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"fahrenheit\")"]}
7 | {:text ["45°" "45 céimeanna"]
8 | :checks [#clj-duckling/corpus "(temperature 45 \"degree\")"]}
9 | {:text ["-10°" "- 10 céimeanna" "10 céimeanna faoi bhun náid"]
10 | :checks [#clj-duckling/corpus "(temperature -10 \"degree\")"]}]}
--------------------------------------------------------------------------------
/src/clj_duckling/dims/duration.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.dims.duration
2 | (:require
3 | [clj-duckling.util.engine :refer [export-value]]
4 | [clj-duckling.util.time :as t]))
5 |
6 | (defmethod export-value :duration [{:keys [value unit] :as token} _]
7 | (let [[[unit val] & more] (seq value)
8 | add-fields (when-not more {:value val
9 | :unit unit})]
10 | (merge value
11 | add-fields
12 | {:normalized {:value (try
13 | (t/period->duration value)
14 | (catch ArithmeticException e (.getMessage e)))
15 | :unit "second"}})))
16 |
--------------------------------------------------------------------------------
/resources/languages/fr/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "37 ° celsius" "37 degres Celsius" "37 degré C" "trente sept celsius" "37 degré C" "trente sept celsius"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"celsius\")"]}
5 | {:text ["70°F" "70 ° Fahrenheit" "70 degrès F" "soixante-dix Fahrenheit"]
6 | :checks [#clj-duckling/corpus "(temperature 70 \"fahrenheit\")"]}
7 | {:text ["45°" "45 degrés" "45 deg."]
8 | :checks [#clj-duckling/corpus "(temperature 45 \"degree\")"]}
9 | {:text ["-10°" "- 10 degres" "10 degres en dessous de zero"]
10 | :checks [#clj-duckling/corpus "(temperature -10 \"degree\")"]}]}
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile
2 | #
3 | # Converts org-mode to Markdown
4 | #
5 | # Run "make" (or "make all") to convert to all other formats
6 | #
7 | # Run "make clean" to delete converted files
8 |
9 | # Convert all files in this directory that have a .md suffix
10 | SOURCE_DOCS := $(wildcard *.org)
11 |
12 | EXPORTED_DOCS= $(SOURCE_DOCS:.org=.md)
13 |
14 |
15 | RM=/bin/rm
16 |
17 | PANDOC=/usr/bin/pandoc
18 |
19 | # PANDOC_OPTIONS=--smart --standalone
20 | PANDOC_OPTIONS=--from org --to markdown_github --standalone
21 |
22 | %.md : %.org
23 | $(PANDOC) $(PANDOC_OPTIONS) -o $@ $<
24 |
25 | # Targets and dependencies
26 |
27 | .PHONY: all clean
28 |
29 | all : $(EXPORTED_DOCS)
30 |
31 | clean:
32 | - $(RM) $(EXPORTED_DOCS)
33 |
--------------------------------------------------------------------------------
/resources/languages/et/rules/_temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp", :pattern "(dim :number)", :production "{:dim :temperature, :latent true, :value (:value %1)}"}
2 | #clj-duckling.engine/rule {:name " degrees", :pattern "[(dim :temperature) #\"(?i)(deg(ree?)?s?\\.?)|°\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"degree\"}))"}
3 | #clj-duckling.engine/rule {:name " Celcius", :pattern "[(dim :temperature) #\"(?i)c(el[cs]?(ius)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"celsius\"}))"}
4 | #clj-duckling.engine/rule {:name " Fahrenheit", :pattern "[(dim :temperature) #\"(?i)f(ah?rh?eh?n(h?eit)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}]
--------------------------------------------------------------------------------
/resources/languages/hr/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp", :pattern "(dim :number)", :production "{:dim :temperature, :latent true, :value (:value %1)}"}
2 | #clj-duckling.engine/rule {:name " stupnjevi", :pattern "[(dim :temperature) #\"(?i)deg\\.?|stupa?nj((ev)?a)?|°\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"degree\"}))"}
3 | #clj-duckling.engine/rule {:name " Celzij", :pattern "[(dim :temperature) #\"(?i)c(el[z]?(ij(a)?)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"celsius\"}))"}
4 | #clj-duckling.engine/rule {:name " Fahrenheit", :pattern "[(dim :temperature) #\"(?i)f(ah?rh?eh?n(h?eit)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}]
--------------------------------------------------------------------------------
/resources/languages/it/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp", :pattern "(dim :number)", :production "{:dim :temperature, :latent true, :value (:value %1)}"}
2 | #clj-duckling.engine/rule {:name " degrees", :pattern "[(dim :temperature) #\"(?i)(grad[io]?\\.?)|°\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"degree\"}))"}
3 | #clj-duckling.engine/rule {:name " Celcius", :pattern "[(dim :temperature) #\"(?i)(c((el[cs]?(ius)?)|(entigrad[io]))?\\.?)\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"celsius\"}))"}
4 | #clj-duckling.engine/rule {:name " Fahrenheit", :pattern "[(dim :temperature) #\"(?i)f(ah?rh?eh?n(h?eit)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}]
--------------------------------------------------------------------------------
/resources/languages/et/corpus/_communication.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["650-283-4757" "+1 6502834757" "+33 4 76095663" "06 2070 2220" " (650)-283-4757 ext 897"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :phone-number (:dim token)) (= (:text token) (:val token))))"]}
5 | {:text ["http://www.bla.com" "www.bla.com:8080/path" "https://myserver?foo=bar" "cnn.com/info" "bla.com/path/path?ext=%23&foo=bla" "localhost" "localhost:8000" "http://kimchi"]
6 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :url (:dim token)) (= (:text token) (:val token))))"]}
7 | {:text ["alex@wit.ai" "alex.lebrun@mail.wit.com"]
8 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :email (:dim token)) (= (:text token) (:val token))))"]}]}
--------------------------------------------------------------------------------
/resources/languages/fr/corpus/communication.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["650-283-4757" "+1 6502834757" "+33 4 76095663" "06 2070 2220" " (650)-283-4757 ext 897"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :phone-number (:dim token)) (= (:text token) (:val token))))"]}
5 | {:text ["http://www.bla.com" "www.bla.com:8080/path" "https://myserver?foo=bar" "cnn.com/info" "bla.com/path/path?ext=%23&foo=bla" "localhost" "localhost:8000" "http://kimchi"]
6 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :url (:dim token)) (= (:text token) (:val token))))"]}
7 | {:text ["alex@wit.ai" "alex.lebrun@mail.wit.com"]
8 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :email (:dim token)) (= (:text token) (:val token))))"]}]}
--------------------------------------------------------------------------------
/resources/languages/ko/corpus/communication.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["650-283-4757" "+1 6502834757" "+33 4 76095663" "06 2070 2220" " (650)-283-4757 ext 897"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :phone-number (:dim token)) (= (:text token) (:val token))))"]}
5 | {:text ["http://www.bla.com" "www.bla.com:8080/path" "https://myserver?foo=bar" "cnn.com/info" "bla.com/path/path?ext=%23&foo=bla" "localhost" "localhost:8000" "http://kimchi"]
6 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :url (:dim token)) (= (:text token) (:val token))))"]}
7 | {:text ["alex@wit.ai" "alex.lebrun@mail.wit.com"]
8 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :email (:dim token)) (= (:text token) (:val token))))"]}]}
--------------------------------------------------------------------------------
/resources/languages/hr/corpus/communication.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["650-283-4757" "+1 6502834757" "+33 4 76095663" "06 2070 2220" " (650)-283-4757 ext 897"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :phone-number (:dim token)) (= (:text token) (:val token))))"]}
5 | {:text ["http://www.bla.com" "http://www.bla.hr" "www.bla.com:8080/path" "https://myserver?foo=bar" "cnn.com/info" "bla.com/path/path?ext=%23&foo=bla" "localhost" "localhost:8000" "http://kimchi"]
6 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :url (:dim token)) (= (:text token) (:val token))))"]}
7 | {:text ["alex@wit.ai" "alex.lebrun@mail.wit.com"]
8 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :email (:dim token)) (= (:text token) (:val token))))"]}]}
--------------------------------------------------------------------------------
/resources/languages/it/corpus/communication.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["650-283-4757" "+1 6502834757" "+33 4 76095663" "06 2070 2220" " (650)-283-4757 ext 897"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :phone-number (:dim token)) (= (:text token) (:val token))))"]}
5 | {:text ["http://www.bla.com" "www.bla.com:8080/path" "https://myserver?foo=bar" "cnn.com/info" "bla.com/path/path?ext=%23&foo=bla" "localhost" "localhost:8000" "http://kimchi"]
6 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :url (:dim token)) (= (:text token) (:val token))))"]}
7 | {:text ["alex@wit.ai" "tedi chiocciola wit.com" "alex.lebrun@mail.wit.com"]
8 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :email (:dim token)) (= (:text token) (:val token))))"]}]}
--------------------------------------------------------------------------------
/resources/languages/it/corpus/temperature.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["37°C" "37 ° celsius" "37 ° centigradi" "37 gradi Celsius" "37 gradi Centigradi" "trentasette celsius" "trentasette gradi centigradi"]
4 | :checks [#clj-duckling/corpus "(temperature 37 \"celsius\")"]}
5 | {:text ["1 grado centigrado"]
6 | :checks [#clj-duckling/corpus "(temperature 1 \"celsius\")"]}
7 | {:text ["70°F" "70 ° Fahrenheit" "70 gradi F" "70 gradi Fahreneit" "settanta Fahrenheit"]
8 | :checks [#clj-duckling/corpus "(temperature 70 \"fahrenheit\")"]}
9 | {:text ["45°" "45 gradi"]
10 | :checks [#clj-duckling/corpus "(temperature 45 \"degree\")"]}
11 | {:text ["1 grado"]
12 | :checks [#clj-duckling/corpus "(temperature 1 \"degree\")"]}]}
--------------------------------------------------------------------------------
/dev/src/dev.clj:
--------------------------------------------------------------------------------
1 | (ns dev
2 | (:refer-clojure :exclude [test])
3 | (:require
4 | [clojure.repl :refer :all]
5 | [clojure.java.io :as io]
6 | [clojure.spec.alpha :as s]
7 | [clojure.tools.namespace.repl :refer [refresh]]
8 | [fipp.edn :refer [pprint] :rename {pprint fipp}]
9 | [criterium.core :as crt]
10 | [integrant.core :as ig]
11 | [integrant.repl :refer [clear halt go init prep reset]]
12 | [integrant.repl.state :refer [config system]]
13 | [duct.logger :as logger :refer [log]]
14 | [clj-duckling.core :as d]
15 | [clj-duckling.system :as sys]
16 | [clj-duckling.spec]))
17 |
18 | (defn read-config []
19 | (sys/read-config "dev.edn"))
20 |
21 | (clojure.tools.namespace.repl/set-refresh-dirs "dev/src" "src")
22 |
23 | (integrant.repl/set-prep! (comp sys/prep read-config))
24 |
--------------------------------------------------------------------------------
/resources/languages/pt/corpus/communication.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["19 99999999" "999999999" "+33 19 76095663" "06 2070 2220" " (19) 997424919" "+55 19 992842606" " (650)-283-4757 ramal 897"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :phone-number (:dim token)) (= (:text token) (:val token))))"]}
5 | {:text ["http://www.bla.com" "www.bla.com:8080/path" "https://myserver?foo=bar" "cnn.com/info" "bla.com/path/path?ext=%23&foo=bla" "localhost" "localhost:8000" "http://kimchi"]
6 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :url (:dim token)) (= (:text token) (:val token))))"]}
7 | {:text ["alex@wit.ai" "alex.lebrun@mail.wit.com"]
8 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :email (:dim token)) (= (:text token) (:val token))))"]}]}
--------------------------------------------------------------------------------
/src/clj_duckling/system.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.system
2 | "Integrant system specific functions"
3 | (:require
4 | [clojure.java.io :as io]
5 | [integrant.core :as ig]))
6 |
7 | (def system nil)
8 |
9 | (defn read-config [filename]
10 | (ig/read-string (slurp (io/resource filename))))
11 |
12 | (defn prep [config]
13 | (doto config ig/load-namespaces))
14 |
15 |
16 | (defn make-test-logger [level]
17 | {
18 | :duct.logger/timbre {:level level
19 | :appenders {:duct.logger.timbre/brief (ig/ref :duct.logger.timbre/brief)}},
20 | :duct.logger.timbre/brief {:min-level level}
21 | }
22 | )
23 |
24 | (defn get-test-module
25 | [configfile ukey]
26 | (-> configfile
27 | io/file
28 | slurp
29 | ig/read-string
30 | prep
31 | ig/init
32 | ukey))
33 |
--------------------------------------------------------------------------------
/resources/languages/es/corpus/communication.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["650-283-4757" "+1 6502834757" "+33 4 76095663" "06 2070 2220" " (650)-283-4757 ext 897"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :phone-number (:dim token)) (= (:text token) (:val token))))"]}
5 | {:text ["http://www.bla.com" "www.bla.com:8080/path" "https://myserver?foo=bar" "cnn.com/info" "bla.com/path/path?ext=%23&foo=bla" "localhost" "localhost:8000" "http://kimchi"]
6 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :url (:dim token)) (= (:text token) (:val token))))"]}
7 | {:text ["alex@wit.ai" "alex.lebrun@mail.wit.com" "alex-lebrun@mail.wit.com" "alex_lebrun@mail.wit.com"]
8 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :email (:dim token)) (= (:text token) (:val token))))"]}]}
--------------------------------------------------------------------------------
/resources/languages/et/rules/_communication.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "phone number", :pattern "#\"(?i)(\\+?[0-9\\(][0-9\\- \\(\\)\\.]{6,16}( ?e?xt?\\.? ?\\d+)?)\"", :production "{:dim :phone-number, :value (-> %1 :groups first)}"}
2 | #clj-duckling.engine/rule {:name "url", :pattern "#\"((https?://)?(\\w+\\.)+\\w{2,4}(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
3 | #clj-duckling.engine/rule {:name "localhost url", :pattern "#\"((https?://)?localhost(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
4 | #clj-duckling.engine/rule {:name "local url", :pattern "#\"((https?://)\\w+(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
5 | #clj-duckling.engine/rule {:name "email", :pattern "#\"([\\w\\.]+@[\\w\\.]+)\"", :production "{:dim :email, :value (-> %1 :groups first)}"}]
--------------------------------------------------------------------------------
/resources/languages/ro/corpus/communication.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0743115099" "0743 115 099" "074 31 15 099" "0743 11 50 99" "+4 0743115099" "004 0743115099" "0743115099 int 897" "650-283-4757" "+1 6502834757" "+33 4 76095663" "06 2070 2220" "(650)-283-4757 ext 897"]
4 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :phone-number (:dim token)) (= (:text token) (:val token))))"]}
5 | {:text ["http://www.bla.com" "www.bla.com:8080/path" "https://myserver?foo=bar" "cnn.com/info" "bla.com/path/path?ext=%23&foo=bla" "localhost" "localhost:8000" "http://kimchi"]
6 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :url (:dim token)) (= (:text token) (:val token))))"]}
7 | {:text ["alex@wit.ai" "alex.lebrun@mail.wit.com"]
8 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :email (:dim token)) (= (:text token) (:val token))))"]}]}
9 |
--------------------------------------------------------------------------------
/resources/languages/es/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp", :pattern "(dim :number)", :production "{:dim :temperature, :latent true, :value (:value %1)}"}
2 | #clj-duckling.engine/rule {:name " temp", :pattern "[(dim :temperature) #\"(?i)(grados?)|°\"]", :production "(dissoc %1 :latent)"}
3 | #clj-duckling.engine/rule {:name " Celsius", :pattern "[(dim :temperature) #\"(?i)(cent(i|í)grados?|c(el[cs]?(ius)?)?\\.?)\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"C\"}))"}
4 | #clj-duckling.engine/rule {:name " Fahrenheit", :pattern "[(dim :temperature) #\"(?i)f(ah?reh?n(h?eit)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"F\"}))"}
5 | #clj-duckling.engine/rule {:name " temp bajo cero", :pattern "[(dim :temperature) #\"(?i)((grados?)|°)?( bajo cero)\"]", :production "(-> %1 (dissoc :latent) (merge {:value (* -1 (-> %1 :value))}))"}]
--------------------------------------------------------------------------------
/resources/languages/fr/corpus/finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["$10" "10$" "dix dollars"]
4 | :checks [#clj-duckling/corpus "(money 10 \"$\")"]}
5 | {:text ["$10.000" "10K$" "$10k"]
6 | :checks [#clj-duckling/corpus "(money 10000 \"$\")"]}
7 | {:text ["USD1,23"]
8 | :checks [#clj-duckling/corpus "(money 1.23 \"USD\")"]}
9 | {:text ["20€" "20 euros" "20 Euro" "20 Euros" "EUR 20"]
10 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
11 | {:text ["EUR29,99"]
12 | :checks [#clj-duckling/corpus "(money 29.99 \"EUR\")"]}
13 | {:text ["3 balles"]
14 | :checks [#clj-duckling/corpus "(money 3)"]}
15 | {:text ["£9" "neuf pounds"]
16 | :checks [#clj-duckling/corpus "(money 9 \"£\")"]}
17 | {:text ["GBP3,01" "GBP 3,01"]
18 | :checks [#clj-duckling/corpus "(money 3.01 \"GBP\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/pt/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp", :pattern "(dim :number)", :production "{:dim :temperature, :latent true, :value (:value %1)}"}
2 | #clj-duckling.engine/rule {:name " temp", :pattern "[(dim :temperature) #\"(?i)(graus?)|°\"]", :production "(dissoc %1 :latent)"}
3 | #clj-duckling.engine/rule {:name " Celsius", :pattern "[(dim :temperature) #\"(?i)(cent(i|í)grados?|c(el[cs]?(ius)?)?\\.?)\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"C\"}))"}
4 | #clj-duckling.engine/rule {:name " Fahrenheit", :pattern "[(dim :temperature) #\"(?i)f(ah?reh?n(h?eit)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"F\"}))"}
5 | #clj-duckling.engine/rule {:name " temp abaixo de zero", :pattern "[(dim :temperature) #\"(?i)((graus?)|°)?( abaixo (de)? zero)\"]", :production "(-> %1 (dissoc :latent) (merge {:value (* -1 (-> %1 :value))}))"}]
--------------------------------------------------------------------------------
/resources/languages/fr/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp", :pattern "(dim :number)", :production "{:dim :temperature, :latent true, :value (:value %1)}"}
2 | #clj-duckling.engine/rule {:name " degrees", :pattern "[(dim :temperature) #\"(?i)(deg(r[éeè])?s?\\.?)|°\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"degree\"}))"}
3 | #clj-duckling.engine/rule {:name " Celsius", :pattern "[(dim :temperature) #\"(?i)c(el[cs]?(ius)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"celsius\"}))"}
4 | #clj-duckling.engine/rule {:name " Fahrenheit", :pattern "[(dim :temperature) #\"(?i)f(ah?reh?n(h?eit)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}
5 | #clj-duckling.engine/rule {:name " en dessous de zero", :pattern "[(dim :temperature) #\"(?i)en dessous de (0|z[ée]ro)\"]", :production "(-> %1 (dissoc :latent) (merge {:value (* -1 (-> %1 :value))}))"}]
--------------------------------------------------------------------------------
/resources/languages/ga/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp", :pattern "(dim :number)", :production "{:dim :temperature, :latent true, :value (:value %1)}"}
2 | #clj-duckling.engine/rule {:name " céim", :pattern "[(dim :temperature) #\"(?i)g?ch?[ée]im(e(anna)?)?|°\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"degree\"}))"}
3 | #clj-duckling.engine/rule {:name " Celsius", :pattern "[(dim :temperature) #\"(?i)ceinteagr[áa]d|c(el[cs]?(ius)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"celsius\"}))"}
4 | #clj-duckling.engine/rule {:name " Fahrenheit", :pattern "[(dim :temperature) #\"(?i)f(ah?reh?n(h?eit)?)?\\.?\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}
5 | #clj-duckling.engine/rule {:name " faoi bhun náid", :pattern "[(dim :temperature) #\"(?i)faoi bhun (0|n[aá]id)\"]", :production "(-> %1 (dissoc :latent) (merge {:value (* -1 (-> %1 :value))}))"}]
--------------------------------------------------------------------------------
/resources/languages/ko/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp", :pattern "(dim :number)", :production "{:dim :temperature, :latent true, :value (:value %1)}"}
2 | #clj-duckling.engine/rule {:name " degrees", :pattern "[(dim :temperature) #\"도|°\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"degree\"}))"}
3 | #clj-duckling.engine/rule {:name "섭씨 ", :pattern "[#\"(섭씨)\" (dim :temperature)]", :production "(-> %2 (dissoc :latent) (merge {:unit \"celsius\"}))"}
4 | #clj-duckling.engine/rule {:name " °C", :pattern "[(dim :temperature) #\"(?i)c\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"celsius\"}))"}
5 | #clj-duckling.engine/rule {:name "화씨 ", :pattern "[#\"(화씨)\" (dim :temperature)]", :production "(-> %2 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}
6 | #clj-duckling.engine/rule {:name " °F", :pattern "[(dim :temperature) #\"(?i)f\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}]
--------------------------------------------------------------------------------
/resources/languages/ro/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp"
2 | :pattern "(dim :number)"
3 | :production "{:dim :temperature, :latent true, :value (:value %1)}"}
4 | #clj-duckling.engine/rule {:name " grade"
5 | :pattern "[(dim :temperature) #\"(?i)(grade)|°\"]"
6 | :production "(-> %1 (dissoc :latent) (merge {:unit \"degree\"}))"}
7 | #clj-duckling.engine/rule {:name " Celcius"
8 | :pattern "[(dim :temperature) #\"(?i)c(el[cs]?(ius)?)?\\.?\"]"
9 | :production "(-> %1 (dissoc :latent) (merge {:unit \"celsius\"}))"}
10 | #clj-duckling.engine/rule {:name " Fahrenheit"
11 | :pattern "[(dim :temperature) #\"(?i)f(ah?rh?eh?n(h?eit)?)?\\.?\"]"
12 | :production "(-> %1 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}]
13 |
--------------------------------------------------------------------------------
/resources/languages/en/corpus/communication.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["650-283-4757"
4 | "+1 6502834757" "+33 4 76095663"
5 | "06 2070 2220"
6 | "(650)-283-4757 ext 897"]
7 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :phone-number (:dim token)) (= (:text token) (:val token))))"]}
8 | {:text ["http://www.bla.com"
9 | "www.bla.com:8080/path"
10 | "https://myserver?foo=bar"
11 | "cnn.com/info"
12 | "bla.com/path/path?ext=%23&foo=bla"
13 | "localhost" "localhost:8000"
14 | "http://kimchi"]
15 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :url (:dim token)) (= (:text token) (:val token))))"]}
16 | {:text ["alex@wit.ai"
17 | "alex.lebrun@mail.wit.com"]
18 | :checks [#clj-duckling/corpus "(fn [token _] (and (= :email (:dim token)) (= (:text token) (:val token))))"]}]}
19 |
--------------------------------------------------------------------------------
/resources/languages/en/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp",
2 | :pattern "(dim :number)",
3 | :production "{:dim :temperature, :latent true, :value (:value %1)}"}
4 | #clj-duckling.engine/rule {:name " degrees",
5 | :pattern "[(dim :temperature) #\"(?i)(deg(ree?)?s?\\.?)|°\"]",
6 | :production "(-> %1 (dissoc :latent) (merge {:unit \"degree\"}))"}
7 | #clj-duckling.engine/rule {:name " Celcius",
8 | :pattern "[(dim :temperature) #\"(?i)c(el[cs]?(ius)?)?\\.?\"]",
9 | :production "(-> %1 (dissoc :latent) (merge {:unit \"celsius\"}))"}
10 | #clj-duckling.engine/rule {:name " Fahrenheit",
11 | :pattern "[(dim :temperature) #\"(?i)f(ah?rh?eh?n(h?eit)?)?\\.?\"]",
12 | :production "(-> %1 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}]
13 |
--------------------------------------------------------------------------------
/resources/languages/ja/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp", :pattern "(dim :number)", :production "{:dim :temperature, :latent true, :value (:value %1)}"}
2 | #clj-duckling.engine/rule {:name " degrees", :pattern "[(dim :temperature) #\"度|°\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"degree\"}))"}
3 | #clj-duckling.engine/rule {:name " Celcius", :pattern "[(dim :temperature) #\"摂氏[°度]|°C\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"celsius\"}))"}
4 | #clj-duckling.engine/rule {:name "Celcius ", :pattern "[#\"摂氏\" (dim :temperature) #\"度|°\"]", :production "(-> %2 (dissoc :latent) (merge {:unit \"celsius\"}))"}
5 | #clj-duckling.engine/rule {:name " Fahrenheit", :pattern "[(dim :temperature) #\"華氏[°度]|°F\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}
6 | #clj-duckling.engine/rule {:name "Fahrenheit ", :pattern "[#\"華氏\" (dim :temperature) #\"度|°\"]", :production "(-> %2 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}]
--------------------------------------------------------------------------------
/resources/languages/es/corpus/finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["$10" "10$" "diez dollars"]
4 | :checks [#clj-duckling/corpus "(money 10 \"$\")"]}
5 | {:text ["$10.000" "10K$" "$10k"]
6 | :checks [#clj-duckling/corpus "(money 10000 \"$\")"]}
7 | {:text ["USD1,23"]
8 | :checks [#clj-duckling/corpus "(money 1.23 \"USD\")"]}
9 | {:text ["20€" "20 euros" "20 Euro" "20 Euros" "EUR 20"]
10 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
11 | {:text ["EUR29,99"]
12 | :checks [#clj-duckling/corpus "(money 29.99 \"EUR\")"]}
13 | {:text ["3 balles"]
14 | :checks [#clj-duckling/corpus "(money 3)"]}
15 | {:text ["£9" "nueve pounds"]
16 | :checks [#clj-duckling/corpus "(money 9 \"£\")"]}
17 | {:text ["GBP3,01" "GBP 3,01"]
18 | :checks [#clj-duckling/corpus "(money 3.01 \"GBP\")"]}
19 | {:text ["15 Pt" "15pta" "15Ptas"]
20 | :checks [#clj-duckling/corpus "(money 15 \"PTS\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/zh/rules/temperature.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "number as temp", :pattern "(dim :number)", :production "{:dim :temperature, :latent true, :value (:value %1)}"}
2 | #clj-duckling.engine/rule {:name " degrees", :pattern "[(dim :temperature) #\"度|°\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"degree\"}))"}
3 | #clj-duckling.engine/rule {:name " Celcius", :pattern "[(dim :temperature) #\"[摄攝]氏[°度]|°C\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"celsius\"}))"}
4 | #clj-duckling.engine/rule {:name "Celcius ", :pattern "[#\"[摄攝]氏\" (dim :temperature) #\"度|°\"]", :production "(-> %2 (dissoc :latent) (merge {:unit \"celsius\"}))"}
5 | #clj-duckling.engine/rule {:name " Fahrenheit", :pattern "[(dim :temperature) #\"[华華]氏[°度]|°F\"]", :production "(-> %1 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}
6 | #clj-duckling.engine/rule {:name "Fahrenheit ", :pattern "[#\"[华華]氏\" (dim :temperature) #\"度|°\"]", :production "(-> %2 (dissoc :latent) (merge {:unit \"fahrenheit\"}))"}]
--------------------------------------------------------------------------------
/resources/languages/ga/corpus/measure.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["3 ciliméadair" "3 km" "3km" "3k"]
4 | :checks [#clj-duckling/corpus "(distance 3 \"kilometre\" {:value 3000, :unit \"metre\"})"]}
5 | {:text ["3.0 km"]
6 | :checks [#clj-duckling/corpus "(distance 3.0 \"kilometre\" {:value 3000.0, :unit \"metre\"})"]}
7 | {:text ["8 mhíle" "8 míle"]
8 | :checks [#clj-duckling/corpus "(distance 8 \"mile\" {:value 12872, :unit \"metre\"})"]}
9 | {:text ["9m"]
10 | :checks [#clj-duckling/corpus "(distance 9 \"m\")"]}
11 | {:text ["2cm" "2 cheintiméadar"]
12 | :checks [#clj-duckling/corpus "(distance 2 \"centimetre\" {:value 0.02, :unit \"metre\"})"]}
13 | {:text ["250 millilítir" "250 millilitir" "250ml" "250 ml"]
14 | :checks [#clj-duckling/corpus "(volume 250 \"millilitre\" {:value 0.25, :unit \"litre\"})"]}
15 | {:text ["2 lítir"]
16 | :checks [#clj-duckling/corpus "(volume 2 \"litre\")"]}
17 | {:text ["5 galúin"]
18 | :checks [#clj-duckling/corpus "(volume 5 \"gallon\" {:value 11.355, :unit \"litre\"})"]}]}
--------------------------------------------------------------------------------
/test/config_classifier1.edn:
--------------------------------------------------------------------------------
1 | {
2 | :clj-duckling.model/classifier {:id "test-classifier"
3 | :language "ro"
4 | :loadbin? false
5 | :corpus #ig/ref :clj-duckling.corpus/edn
6 | :rules #ig/ref :clj-duckling.engine/edn
7 | :logger #ig/ref :duct.logger/timbre}
8 |
9 | :clj-duckling.corpus/edn {:id "test-corpus-edn"
10 | :language "ro"
11 | :dirpath "resources/languages/ro/corpus"
12 | :logger #ig/ref :duct.logger/timbre}
13 |
14 | :clj-duckling.engine/edn {:id "test-rules-edn"
15 | :language "ro"
16 | :dirpath "resources/languages/ro/rules"
17 | :logger #ig/ref :duct.logger/timbre}
18 |
19 | :duct.logger/timbre {:level :report
20 | :set-root-config? true
21 | :appenders {:duct.logger.timbre/brief #ig/ref :duct.logger.timbre/brief}},
22 |
23 |
24 | :duct.logger.timbre/brief {:min-level :report},
25 | }
26 |
--------------------------------------------------------------------------------
/resources/languages/my/corpus/number.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["၀" "သုံည" "မရှိ"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["၁" "တစ်" "ပထမ"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["၂" "နှစ်" "ဒုတိယ"]
8 | :checks [#clj-duckling/corpus "(number 2)"]}
9 | {:text ["၃" "သုံး" "တတိယ"]
10 | :checks [#clj-duckling/corpus "(number 3)"]}
11 | {:text ["သုံးဆယ်"]
12 | :checks [#clj-duckling/corpus "(number 30)"]}
13 | {:text ["သုံးဆယ့်သုံး"]
14 | :checks [#clj-duckling/corpus "(number 33)"]}
15 | {:text ["ဆယ့်လေး"]
16 | :checks [#clj-duckling/corpus "(number 14)"]}
17 | {:text ["ဆယ့်ခုနှစ်"]
18 | :checks [#clj-duckling/corpus "(number 17)"]}
19 | {:text ["နှစ်ရာ"]
20 | :checks [#clj-duckling/corpus "(number 200)"]}
21 | {:text ["ကိုးရာ"]
22 | :checks [#clj-duckling/corpus "(number 900)"]}
23 | {:text ["ငါးထောင်"]
24 | :checks [#clj-duckling/corpus "(number 5000)"]}
25 | {:text ["ရှစ်သောင်း"]
26 | :checks [#clj-duckling/corpus "(number 80000)"]}]}
--------------------------------------------------------------------------------
/resources/languages/my/corpus/numbers.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["၀" "သုံည" "မရှိ"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["၁" "တစ်" "ပထမ"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["၂" "နှစ်" "ဒုတိယ"]
8 | :checks [#clj-duckling/corpus "(number 2)"]}
9 | {:text ["၃" "သုံး" "တတိယ"]
10 | :checks [#clj-duckling/corpus "(number 3)"]}
11 | {:text ["သုံးဆယ်"]
12 | :checks [#clj-duckling/corpus "(number 30)"]}
13 | {:text ["သုံးဆယ့်သုံး"]
14 | :checks [#clj-duckling/corpus "(number 33)"]}
15 | {:text ["ဆယ့်လေး"]
16 | :checks [#clj-duckling/corpus "(number 14)"]}
17 | {:text ["ဆယ့်ခုနှစ်"]
18 | :checks [#clj-duckling/corpus "(number 17)"]}
19 | {:text ["နှစ်ရာ"]
20 | :checks [#clj-duckling/corpus "(number 200)"]}
21 | {:text ["ကိုးရာ"]
22 | :checks [#clj-duckling/corpus "(number 900)"]}
23 | {:text ["ငါးထောင်"]
24 | :checks [#clj-duckling/corpus "(number 5000)"]}
25 | {:text ["ရှစ်သောင်း"]
26 | :checks [#clj-duckling/corpus "(number 80000)"]}]}
--------------------------------------------------------------------------------
/resources/languages/ga/corpus/time.edn:
--------------------------------------------------------------------------------
1 | {:context {:reference-time #clj-duckling/time "(t -2 2013 2 12 4 30 0)", :min #clj-duckling/time "(t -2 1900)", :max #clj-duckling/time "(t -2 2100)"}
2 |
3 | :tests [{:text ["anois"]
4 | :checks [#clj-duckling/corpus "(datetime 2013 2 12 4 30 0)"]}
5 | {:text ["inniu"]
6 | :checks [#clj-duckling/corpus "(datetime 2013 2 12)"]}
7 | {:text ["inné"]
8 | :checks [#clj-duckling/corpus "(datetime 2013 2 11)"]}
9 | {:text ["arú inné"]
10 | :checks [#clj-duckling/corpus "(datetime 2013 2 10)"]}
11 | {:text ["amárach"]
12 | :checks [#clj-duckling/corpus "(datetime 2013 2 13)"]}
13 | {:text ["arú amárach"]
14 | :checks [#clj-duckling/corpus "(datetime 2013 2 14)"]}
15 | {:text ["dé luain" "an luan" "an luan seo"]
16 | :checks [#clj-duckling/corpus "(datetime 2013 2 18 :day-of-week 1)"]}
17 | {:text ["an luan seo chugainn" "an luan seo atá ag teacht" "dé luain seo chugainn"]
18 | :checks [#clj-duckling/corpus "(datetime 2013 2 18 :day-of-week 1)"]}
19 | {:text ["18/2/2013"]
20 | :checks [#clj-duckling/corpus "(datetime 2013 2 18)"]}]}
--------------------------------------------------------------------------------
/src/clj_duckling/util/helpers.clj:
--------------------------------------------------------------------------------
1 | (ns clj-duckling.util.helpers
2 | "This namespace contains the common helpers used in rules"
3 | (:require
4 | [clj-time.core :as t]
5 | [clj-duckling.util.core :as util]))
6 |
7 | (defmacro fn& [dim & args-body]
8 | (let [meta-map (when (-> args-body first map?)
9 | (first args-body))
10 | args-body (if meta-map
11 | (rest args-body)
12 | args-body)]
13 | (merge meta-map
14 | `{:dim ~(keyword dim)
15 | :pred (fn ~@args-body)})))
16 |
17 | (defn dim
18 | "Returns a func checking dim of a token and additional preds"
19 | [dim-val & predicates]
20 | (fn [token]
21 | (and (= dim-val (:dim token))
22 | (every? #(% token) predicates))))
23 |
24 | (defn integer
25 | "Return a func (duckling pattern) checking that dim=number and integer=true,
26 | optional range (inclusive), and additional preds"
27 | [& [min max & predicates]]
28 | (fn [token]
29 | (and (= :number (:dim token))
30 | (:integer token)
31 | (or (nil? min) (<= min (:val token)))
32 | (or (nil? max) (<= (:val token) max))
33 | (every? #(% token) predicates))))
34 |
--------------------------------------------------------------------------------
/resources/languages/et/corpus/_finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["$10" "10$" "kümme dollarit"]
4 | :checks [#clj-duckling/corpus "(money 10 \"$\")"]}
5 | {:text ["kümme senti"]
6 | :checks [#clj-duckling/corpus "(money 10 \"cent\")"]}
7 | {:text ["$10,000" "$10 000" "10K$" "$10k"]
8 | :checks [#clj-duckling/corpus "(money 10000 \"$\")"]}
9 | {:text ["USD1.23"]
10 | :checks [#clj-duckling/corpus "(money 1.23 \"USD\")"]}
11 | {:text ["2 dollarit ja 23 senti" "kaks dollarit 23 senti" "2 dollarit 23" "kaks dollarit ja 23"]
12 | :checks [#clj-duckling/corpus "(money 2.23 \"$\")"]}
13 | {:text ["20€" "20 eurot" "20 Euri" "20 Eurot" "EUR 20"]
14 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
15 | {:text ["EUR29.99"]
16 | :checks [#clj-duckling/corpus "(money 29.99 \"EUR\")"]}
17 | {:text ["3 taala"]
18 | :checks [#clj-duckling/corpus "(money 3)"]}
19 | {:text ["£9" "üheksa naela" "üheksa naelsterlingit"]
20 | :checks [#clj-duckling/corpus "(money 9 \"£\")"]}
21 | {:text ["GBP3.01" "GBP 3.01"]
22 | :checks [#clj-duckling/corpus "(money 3.01 \"GBP\")"]}]}
--------------------------------------------------------------------------------
/test/config_classifier2.edn:
--------------------------------------------------------------------------------
1 | {
2 | :clj-duckling.model/classifier {:id "test-classifier"
3 | :language "ro"
4 | :binfile "test/tmp.bin"
5 | :loadbin? false
6 | :corpus #ig/ref :clj-duckling.corpus/edn
7 | :rules #ig/ref :clj-duckling.engine/edn
8 | :logger #ig/ref :duct.logger/timbre}
9 |
10 |
11 | :clj-duckling.corpus/edn {:id "test-corpus-edn"
12 | :language "ro"
13 | :dirpath "resources/languages/ro/corpus"
14 | :logger #ig/ref :duct.logger/timbre}
15 |
16 | :clj-duckling.engine/edn {:id "test-rules-edn"
17 | :language "ro"
18 | :dirpath "resources/languages/ro/rules"
19 | :logger #ig/ref :duct.logger/timbre}
20 |
21 |
22 | :duct.logger/timbre {:level :error
23 | :set-root-config? true
24 | :appenders {:duct.logger.timbre/brief #ig/ref :duct.logger.timbre/brief}},
25 |
26 |
27 | :duct.logger.timbre/brief {:min-level :report},
28 | }
29 |
--------------------------------------------------------------------------------
/resources/languages/fr/rules/communication.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "phone number", :pattern "#\"(?i)(\\+?[0-9\\(][0-9\\- \\(\\)\\.]{6,16}( ?e?xt?\\.? ?\\d+)?)\"", :production "{:dim :phone-number, :value (-> %1 :groups first)}"}
2 | #clj-duckling.engine/rule {:name "phone number given by each number", :pattern "[(integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9)]", :production "{:dim :phone-number, :value (clojure.string/join \"\" [(:value %1) (:value %2) (:value %3) (:value %4) (:value %5) (:value %6) (:value %7) (:value %8) (:value %9) (:value %10)])}"}
3 | #clj-duckling.engine/rule {:name "url", :pattern "#\"((https?://)?(\\w+\\.)+\\w{2,4}(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
4 | #clj-duckling.engine/rule {:name "localhost url", :pattern "#\"((https?://)?localhost(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
5 | #clj-duckling.engine/rule {:name "local url", :pattern "#\"((https?://)\\w+(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
6 | #clj-duckling.engine/rule {:name "email", :pattern "#\"([\\w\\.]+@[\\w\\.]+)\"", :production "{:dim :email, :value (-> %1 :groups first)}"}]
--------------------------------------------------------------------------------
/resources/languages/es/rules/communication.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "phone number", :pattern "#\"(?i)(\\+?[0-9\\(][0-9\\- \\(\\)\\.]{6,16}( ?e?xt?\\.? ?\\d+)?)\"", :production "{:dim :phone-number, :value (-> %1 :groups first)}"}
2 | #clj-duckling.engine/rule {:name "phone number given by each number", :pattern "[(integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9)]", :production "{:dim :phone-number, :value (clojure.string/join \"\" [(:value %1) (:value %2) (:value %3) (:value %4) (:value %5) (:value %6) (:value %7) (:value %8) (:value %9) (:value %10)])}"}
3 | #clj-duckling.engine/rule {:name "url", :pattern "#\"((https?://)?(\\w+\\.)+\\w{2,4}(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
4 | #clj-duckling.engine/rule {:name "localhost url", :pattern "#\"((https?://)?localhost(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
5 | #clj-duckling.engine/rule {:name "local url", :pattern "#\"((https?://)\\w+(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
6 | #clj-duckling.engine/rule {:name "email", :pattern "#\"([\\w\\.\\-_]+@[\\w\\.\\-_]+)\"", :production "{:dim :email, :value (-> %1 :groups first)}"}]
--------------------------------------------------------------------------------
/resources/languages/ko/rules/communication.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "phone number", :pattern "#\"(?i)(\\+?[0-9\\(][0-9\\- \\(\\)\\.]{6,16}( ?e?xt?\\.? ?\\d+)?)\"", :production "{:dim :phone-number, :value (-> %1 :groups first)}"}
2 | #clj-duckling.engine/rule {:name "phone number given by each number", :pattern "[(integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9)]", :production "{:dim :phone-number, :value (clojure.string/join \"\" [(:value %1) (:value %2) (:value %3) (:value %4) (:value %5) (:value %6) (:value %7) (:value %8) (:value %9) (:value %10)])}"}
3 | #clj-duckling.engine/rule {:name "url", :pattern "#\"((https?://)?(\\w+\\.)+[A-z]{2,4}(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
4 | #clj-duckling.engine/rule {:name "localhost url", :pattern "#\"((https?://)?localhost(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
5 | #clj-duckling.engine/rule {:name "local url", :pattern "#\"((https?://)\\w+(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
6 | #clj-duckling.engine/rule {:name "email", :pattern "#\"([\\w\\.\\-_]+@[\\w\\.\\-_]+)\"", :production "{:dim :email, :value (-> %1 :groups first)}"}]
--------------------------------------------------------------------------------
/resources/languages/pt/corpus/finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["$10" "10$" "dez dolares"]
4 | :checks [#clj-duckling/corpus "(money 10 \"$\")"]}
5 | {:text ["$10.000" "10K$" "$10k"]
6 | :checks [#clj-duckling/corpus "(money 10000 \"$\")"]}
7 | {:text ["USD1,23"]
8 | :checks [#clj-duckling/corpus "(money 1.23 \"USD\")"]}
9 | {:text ["20€" "20 euros" "20 Euro" "20 Euros" "EUR 20"]
10 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
11 | {:text ["EUR29,99"]
12 | :checks [#clj-duckling/corpus "(money 29.99 \"EUR\")"]}
13 | {:text ["3 balles"]
14 | :checks [#clj-duckling/corpus "(money 3)"]}
15 | {:text ["£9" "nove libras"]
16 | :checks [#clj-duckling/corpus "(money 9 \"£\")"]}
17 | {:text ["GBP3,01" "GBP 3,01"]
18 | :checks [#clj-duckling/corpus "(money 3.01 \"GBP\")"]}
19 | {:text ["15 Pt" "15pta" "15Ptas"]
20 | :checks [#clj-duckling/corpus "(money 15 \"PTS\")"]}
21 | {:text ["15 reais" "15reais" "15 Reais" "BRL 15"]
22 | :checks [#clj-duckling/corpus "(money 15 \"BRL\")"]}
23 | {:text ["R$2,00" "R$ 2,00" "2,00 reais"]
24 | :checks [#clj-duckling/corpus "(money 2.0 \"BRL\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/id/corpus/finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["$10" "10$" "sepuluh dolar"]
4 | :checks [#clj-duckling/corpus "(money 10 \"$\")"]}
5 | {:text ["$10.000" "10K$" "$10k"]
6 | :checks [#clj-duckling/corpus "(money 10000 \"$\")"]}
7 | {:text ["USD1,23"]
8 | :checks [#clj-duckling/corpus "(money 1.23 \"USD\")"]}
9 | {:text ["2 dolar" "dua dolar"]
10 | :checks [#clj-duckling/corpus "(money 2 \"$\")"]}
11 | {:text ["20€" "20 euros" "20 Euro" "20 Euros" "EUR 20" "dua puluh Euro"]
12 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
13 | {:text ["EUR29,99"]
14 | :checks [#clj-duckling/corpus "(money 29.99 \"EUR\")"]}
15 | {:text ["Rp. 315,00"]
16 | :checks [#clj-duckling/corpus "(money 315.0 \"IDR\")"]}
17 | {:text ["Rp 20" "20 Rupiah" "20Rp" "Rp20"]
18 | :checks [#clj-duckling/corpus "(money 20 \"IDR\")"]}
19 | {:text ["IDR33000" "IDR 33.000"]
20 | :checks [#clj-duckling/corpus "(money 33000 \"IDR\")"]}
21 | {:text ["£9" "sembilan pound"]
22 | :checks [#clj-duckling/corpus "(money 9 \"£\")"]}
23 | {:text ["GBP3,01" "GBP 3,01"]
24 | :checks [#clj-duckling/corpus "(money 3.01 \"GBP\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/ko/corpus/finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["십달러" "십불"]
4 | :checks [#clj-duckling/corpus "(money 10 \"$\")"]}
5 | {:text ["십센트"]
6 | :checks [#clj-duckling/corpus "(money 10 \"cent\")"]}
7 | {:text ["만달러" "만불"]
8 | :checks [#clj-duckling/corpus "(money 10000 \"$\")"]}
9 | {:text ["일점이삼달러" "일쩜이삼달러" "일점이삼불" "일쩜이삼불"]
10 | :checks [#clj-duckling/corpus "(money 1.23 \"$\")"]}
11 | {:text ["이달러이십삼센트" "이불이십삼센트"]
12 | :checks [#clj-duckling/corpus "(money 2.23 \"$\")"]}
13 | {:text ["이십유로" "EUR 20"]
14 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
15 | {:text ["이십구점구구유로" "EUR29.99"]
16 | :checks [#clj-duckling/corpus "(money 29.99 \"EUR\")"]}
17 | {:text ["구파운드"]
18 | :checks [#clj-duckling/corpus "(money 9 \"£\")"]}
19 | {:text ["이천칠백삼십오만원" "27,350,000원" "27350000원"]
20 | :checks [#clj-duckling/corpus "(money 27350000 \"KRW\")"]}
21 | {:text ["이만칠천원" "27,000원" "27000원"]
22 | :checks [#clj-duckling/corpus "(money 27000 \"KRW\")"]}
23 | {:text ["백원" "100원"]
24 | :checks [#clj-duckling/corpus "(money 100 \"KRW\")"]}
25 | {:text ["십원" "10원"]
26 | :checks [#clj-duckling/corpus "(money 10 \"KRW\")"]}]}
--------------------------------------------------------------------------------
/README.org:
--------------------------------------------------------------------------------
1 | As of May 1st, 2017 the Duckling team deprecated the Clojure version in
2 | favor of [[https://github.com/facebookincubator/duckling][the new
3 | Duckling]]. See their
4 | [[https://wit.ai/blog/2017/05/01/new-duckling][blog post announcement]].
5 |
6 | My intention is to continue the clojure development of the Duckling
7 | project so I forked it in this new project.
8 |
9 | * Duckling
10 |
11 |
12 | Duckling is a Clojure library that parses text into structured data:
13 |
14 | #+BEGIN_EXAMPLE
15 | "the car is 2 meters long and costs 3000$." => [{:dim :amount-of-money, :body "3000$", :value {:type "value", :value 3000, :unit "USD"}, :start 35, :end 40}
16 | {:dim :distance, :body "2 meters", :value {:type "value", :value 2, :unit "metre"}, :start 11, :end 19}]
17 | #+END_EXAMPLE
18 |
19 |
20 |
21 | ** Getting started
22 |
23 | For lein add to your project.clj:
24 | [[https://clojars.org/dpom/clj-duckling][https://img.shields.io/clojars/v/dpom/clj-duckling.svg]]
25 |
26 | In =core= source file you can find some examples of how to use the library. My [[https://github.com/dpom/nluserv][nluserv]] project use also clj-duckling.
27 |
28 | See the [[https://dpom.github.io/clj-duckling/][documentation]] and [[https://dpom.github.io/clj-duckling/api/index.html][API]] for more information.
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD License
2 |
3 | For Duckling software
4 |
5 | Copyright (c) 2014, Wit.ai, Inc.
6 | All rights reserved.
7 |
8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
9 |
10 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 |
--------------------------------------------------------------------------------
/PATENTS:
--------------------------------------------------------------------------------
1 | Additional Grant of Patent Rights
2 |
3 | “Software” means the Duckling software distributed by Wit.ai, Inc.
4 |
5 | Wit.ai hereby grants you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (subject to the termination provision below) license under any rights in any patent claims owned by Facebook, to make, have made, use, sell, offer to sell, import, and otherwise transfer the Software. For avoidance of doubt, no license is granted under Facebook’s rights in any patent claims that are infringed by (i) modifications to the Software made by you or a third party, or (ii) the Software in combination with any software or other technology provided by you or a third party.
6 |
7 | The license granted hereunder will terminate, automatically and without notice, for anyone that makes any claim (including by filing any lawsuit, assertion or other action) alleging (a) direct, indirect, or contributory infringement or inducement to infringe any patent: (i) by Wit.ai or any of its subsidiaries or affiliates, whether or not such claim is related to the Software, (ii) by any party if such claim arises in whole or in part from any software, product or service of Wit.ai or any of its subsidiaries or affiliates, whether or not such claim is related to the Software, or (iii) by any party relating to the Software; or (b) that any right in any patent claim of Wit.ai is invalid or unenforceable.
8 |
--------------------------------------------------------------------------------
/resources/languages/hr/rules/communication.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "phone number", :pattern "#\"(?i)(\\+?[0-9\\(][0-9\\- \\(\\)\\.]{6,16}( ?e?xt?\\.? ?\\d+)?)\"", :production "{:dim :phone-number, :value (-> %1 :groups first)}"}
2 | #clj-duckling.engine/rule {:name "phone number given by each number", :pattern "[(integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9)]", :production "{:dim :phone-number, :value (clojure.string/join \"\" [(:value %1) (:value %2) (:value %3) (:value %4) (:value %5) (:value %6) (:value %7) (:value %8) (:value %9) (:value %10)])}"}
3 | #clj-duckling.engine/rule {:name "url", :pattern "#\"(\\b(? %1 :groups first)}"}
4 | #clj-duckling.engine/rule {:name "localhost url", :pattern "#\"((https?://)?localhost(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
5 | #clj-duckling.engine/rule {:name "local url", :pattern "#\"((https?://)\\w+(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
6 | #clj-duckling.engine/rule {:name "email", :pattern "#\"([\\w\\.\\-_]+@[\\w\\.\\-_]+)\"", :production "{:dim :email, :value (-> %1 :groups first)}"}]
--------------------------------------------------------------------------------
/resources/languages/pt/rules/communication.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "phone number", :pattern "#\"(?i)(\\+?[0-9\\(][0-9\\- \\(\\)\\.]{6,16}( ?(ramal) ?\\d+)?)\"", :production "{:dim :phone-number, :value (-> %1 :groups first)}"}
2 | #clj-duckling.engine/rule {:name "phone number given by each number", :pattern "[(integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9)]", :production "{:dim :phone-number, :value (clojure.string/join \"\" [(:value %1) (:value %2) (:value %3) (:value %4) (:value %5) (:value %6) (:value %7) (:value %8) (:value %9) (:value %10)])}"}
3 | #clj-duckling.engine/rule {:name "url", :pattern "#\"(\\b(? %1 :groups first)}"}
4 | #clj-duckling.engine/rule {:name "localhost url", :pattern "#\"((https?://)?localhost(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
5 | #clj-duckling.engine/rule {:name "local url", :pattern "#\"((https?://)\\w+(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
6 | #clj-duckling.engine/rule {:name "email", :pattern "#\"([\\w\\.\\-_]+@[\\w\\.\\-_]+)\"", :production "{:dim :email, :value (-> %1 :groups first)}"}]
--------------------------------------------------------------------------------
/resources/languages/es/corpus/measure.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["3 kilómetros" "3 kilometros" "3 km" "3km" "3k"]
4 | :checks [#clj-duckling/corpus "(distance 3 \"kilometre\" {:value 3000, :unit \"metre\"})"]}
5 | {:text ["3,0 km"]
6 | :checks [#clj-duckling/corpus "(distance 3.0 \"kilometre\" {:value 3000.0, :unit \"metre\"})"]}
7 | {:text ["8 miles"]
8 | :checks [#clj-duckling/corpus "(distance 8 \"mile\" {:value 12872, :unit \"metre\"})"]}
9 | {:text ["9m" "9 metros"]
10 | :checks [#clj-duckling/corpus "(distance 9 \"metre\")"]}
11 | {:text ["2cm" "2 centímetros"]
12 | :checks [#clj-duckling/corpus "(distance 2 \"centimetre\" {:value 0.02, :unit \"metre\"})"]}
13 | {:text ["250 mililitros" "250ml" "250 ml"]
14 | :checks [#clj-duckling/corpus "(volume 250 \"millilitre\" {:value 0.25, :unit \"litre\"})"]}
15 | {:text ["2 litros"]
16 | :checks [#clj-duckling/corpus "(volume 2 \"litre\")"]}
17 | {:text ["3 galón"]
18 | :checks [#clj-duckling/corpus "(volume 3 \"gallon\" {:value 11.355, :unit \"litre\"})"]}
19 | {:text ["3 hectolitros"]
20 | :checks [#clj-duckling/corpus "(volume 300 \"litre\" {:value 30, :unit \"litre\"})"]}
21 | {:text ["medio litro"]
22 | :checks [#clj-duckling/corpus "(volume 0.5 \"litre\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/nl/corpus/measure.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["3 kilometer" "3 km" "3km" "3k"]
4 | :checks [#clj-duckling/corpus "(distance 3 \"kilometre\" {:value 3000, :unit \"metre\"})"]}
5 | {:text ["3,0 km" "3,0km"]
6 | :checks [#clj-duckling/corpus "(distance 3.0 \"kilometre\" {:value 3000.0, :unit \"metre\"})"]}
7 | {:text ["8 mijl"]
8 | :checks [#clj-duckling/corpus "(distance 8 \"mile\" {:value 12872, :unit \"metre\"})"]}
9 | {:text ["9m" "9 m" "9 meter"]
10 | :checks [#clj-duckling/corpus "(distance 9 \"metre\")"]}
11 | {:text ["2cm" "2 cm" "2 centimeter"]
12 | :checks [#clj-duckling/corpus "(distance 2 \"centimetre\" {:value 0.02, :unit \"metre\"})"]}
13 | {:text ["250 mililiter" "250ml" "250 ml"]
14 | :checks [#clj-duckling/corpus "(volume 250 \"millilitre\" {:value 0.25, :unit \"litre\"})"]}
15 | {:text ["2 liter" "2l" "2 l"]
16 | :checks [#clj-duckling/corpus "(volume 2 \"litre\")"]}
17 | {:text ["3 gallon"]
18 | :checks [#clj-duckling/corpus "(volume 3 \"gallon\" {:value 11.355, :unit \"litre\"})"]}
19 | {:text ["3 hectoliter"]
20 | :checks [#clj-duckling/corpus "(volume 300 \"litre\" {:value 30, :unit \"litre\"})"]}
21 | {:text ["halve liter"]
22 | :checks [#clj-duckling/corpus "(volume 0.5 \"litre\")"]}]}
--------------------------------------------------------------------------------
/test/config_tool.edn:
--------------------------------------------------------------------------------
1 | {
2 | :clj-duckling.tool/duckling {:id "test-tool"
3 | :model #ig/ref :clj-duckling.model/classifier
4 | :rules #ig/ref :clj-duckling.engine/edn
5 | :logger #ig/ref :duct.logger/timbre}
6 |
7 |
8 | :clj-duckling.model/classifier {:id "test-classifier"
9 | :language "ro"
10 | :loadbin? false
11 | :corpus #ig/ref :clj-duckling.corpus/edn
12 | :rules #ig/ref :clj-duckling.engine/edn
13 | :logger #ig/ref :duct.logger/timbre}
14 |
15 |
16 | :clj-duckling.corpus/edn {:id "test-corpus-edn"
17 | :language "ro"
18 | :dirpath "resources/languages/ro/corpus"
19 | :logger #ig/ref :duct.logger/timbre}
20 |
21 | :clj-duckling.engine/edn {:id "test-rules-edn"
22 | :language "ro"
23 | :dirpath "resources/languages/ro/rules"
24 | :logger #ig/ref :duct.logger/timbre}
25 |
26 |
27 | :duct.logger/timbre {:level :error
28 | :set-root-config? true
29 | :appenders {:duct.logger.timbre/brief #ig/ref :duct.logger.timbre/brief}},
30 |
31 |
32 | :duct.logger.timbre/brief {:min-level :report},
33 | }
34 |
--------------------------------------------------------------------------------
/resources/languages/ro/corpus/finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["10 lei" "10 de lei" "10 ron" "10 RON"]
4 | :checks [#clj-duckling/corpus "(money 10 \"RON\")"]}
5 | {:text ["50 bani" "50 de bani" "50 BANI"]
6 | :checks [#clj-duckling/corpus "(money 50 \"ban\")"]}
7 | {:text ["10,5 lei" "10,5 ron" "10 lei si 50 bani"]
8 | :checks [#clj-duckling/corpus "(money 10.5 \"RON\")"]}
9 | {:text ["10$" "zece dolari"]
10 | :checks [#clj-duckling/corpus "(money 10 \"USD\")"]}
11 | {:text ["zece centi" "zece cenți"]
12 | :checks [#clj-duckling/corpus "(money 10 \"cent\")"]}
13 | {:text ["2 dolari"]
14 | :checks [#clj-duckling/corpus "(money 2 \"USD\")"]}
15 | {:text ["2 centi"]
16 | :checks [#clj-duckling/corpus "(money 2 \"cent\")"]}
17 | {:text ["23 centi"]
18 | :checks [#clj-duckling/corpus "(money 23 \"cent\")"]}
19 | {:text ["2 dolari si 23 centi" "2 dolari și 23 cenți" "doi dolari si douăzeci si trei centi" "doi dolari și douăzeci și trei cenți"]
20 | :checks [#clj-duckling/corpus "(money 2.23 \"USD\")"]}
21 | {:text ["20€" "20 euro" "20 Euro"]
22 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
23 | {:text ["noua lire" "nouă lire"]
24 | :checks [#clj-duckling/corpus "(money 9 \"GBP\")"]}
25 | {:text ["aprox 50 lei" "aprox 50 de lei"]
26 | :checks [#clj-duckling/corpus "(money 50 \"RON\" \"approximate\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/pt/corpus/measure.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["3 kilómetros" "3 kilometros" "3 km" "3km" "3k"]
4 | :checks [#clj-duckling/corpus "(distance 3 \"kilometre\" {:value 3000, :unit \"metre\"})"]}
5 | {:text ["3,0 km"]
6 | :checks [#clj-duckling/corpus "(distance 3.0 \"kilometre\" {:value 3000.0, :unit \"metre\"})"]}
7 | {:text ["8 milhas"]
8 | :checks [#clj-duckling/corpus "(distance 8 \"mile\" {:value 12872, :unit \"metre\"})"]}
9 | {:text ["9m" "9 metros"]
10 | :checks [#clj-duckling/corpus "(distance 9 \"metre\")"]}
11 | {:text ["2cm" "2 centímetros"]
12 | :checks [#clj-duckling/corpus "(distance 2 \"centimetre\" {:value 0.02, :unit \"metre\"})"]}
13 | {:text ["250 mililitros" "250ml" "250 ml"]
14 | :checks [#clj-duckling/corpus "(volume 250 \"millilitre\" {:value 0.25, :unit \"litre\"})"]}
15 | {:text ["2 litros"]
16 | :checks [#clj-duckling/corpus "(volume 2 \"litre\")"]}
17 | {:text ["1 galão"]
18 | :checks [#clj-duckling/corpus "(volume 1 \"gallon\" {:value 3.785, :unit \"litre\"})"]}
19 | {:text ["3 galões"]
20 | :checks [#clj-duckling/corpus "(volume 3 \"gallon\" {:value 11.355, :unit \"litre\"})"]}
21 | {:text ["3 hectolitros"]
22 | :checks [#clj-duckling/corpus "(volume 300 \"litre\" {:value 30, :unit \"litre\"})"]}
23 | {:text ["meio litro"]
24 | :checks [#clj-duckling/corpus "(volume 0.5 \"litre\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/es/rules/duration.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "seconde (unit-of-duration)", :pattern "#\"(?i)seg(undo)?s?\"", :production "{:dim :unit-of-duration, :grain :second}"}
2 | #clj-duckling.engine/rule {:name "minute (unit-of-duration)", :pattern "#\"(?i)min(uto)?s?\"", :production "{:dim :unit-of-duration, :grain :minute}"}
3 | #clj-duckling.engine/rule {:name "hour (unit-of-duration)", :pattern "#\"(?i)h(ora)?s?\"", :production "{:dim :unit-of-duration, :grain :hour}"}
4 | #clj-duckling.engine/rule {:name "day (unit-of-duration)", :pattern "#\"(?i)d(í|i)as?\"", :production "{:dim :unit-of-duration, :grain :day}"}
5 | #clj-duckling.engine/rule {:name "week (unit-of-duration)", :pattern "#\"(?i)semanas?\"", :production "{:dim :unit-of-duration, :grain :week}"}
6 | #clj-duckling.engine/rule {:name "month (unit-of-duration)", :pattern "#\"(?i)mes(es)?\"", :production "{:dim :unit-of-duration, :grain :month}"}
7 | #clj-duckling.engine/rule {:name "year (unit-of-duration)", :pattern "#\"(?i)a(n|ñ)os?\"", :production "{:dim :unit-of-duration, :grain :year}"}
8 | #clj-duckling.engine/rule {:name " ", :pattern "[(integer 0) (dim :unit-of-duration)]", :production "{:dim :duration, :value (duration (:grain %2) (:value %1))}"}
9 | #clj-duckling.engine/rule {:name "en ", :pattern "[#\"(?i)en\" (dim :duration)]", :production "(in-duration (:value %2))"}
10 | #clj-duckling.engine/rule {:name "hace ", :pattern "[#\"hace\" (dim :duration)]", :production "(duration-ago (:value %2))"}]
--------------------------------------------------------------------------------
/resources/languages/en/corpus/finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["$10" "10$" "ten dollars"]
4 | :checks [#clj-duckling/corpus "(money 10 \"$\")"]}
5 | {:text ["ten cents"]
6 | :checks [#clj-duckling/corpus "(money 10 \"cent\")"]}
7 | {:text ["$10,000" "10K$" "$10k"]
8 | :checks [#clj-duckling/corpus "(money 10000 \"$\")"]}
9 | {:text ["USD1.23"]
10 | :checks [#clj-duckling/corpus "(money 1.23 \"USD\")"]}
11 | {:text ["2 dollar and 23 cents" "two dollar 23 cents" "2 dollar 23" "two dollar and 23"]
12 | :checks [#clj-duckling/corpus "(money 2.23 \"$\")"]}
13 | {:text ["20€" "20 euros" "20 Euro" "20 Euros" "EUR 20"]
14 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
15 | {:text ["EUR29.99"]
16 | :checks [#clj-duckling/corpus "(money 29.99 \"EUR\")"]}
17 | {:text ["Rs. 20" "Rs 20" "20 Rupees" "20Rs" "Rs20"]
18 | :checks [#clj-duckling/corpus "(money 20 \"INR\")"]}
19 | {:text ["20 Rupees 43" "twenty rupees 43"]
20 | :checks [#clj-duckling/corpus "(money 20.43 \"INR\")"]}
21 | {:text ["INR33"]
22 | :checks [#clj-duckling/corpus "(money 33 \"INR\")"]}
23 | {:text ["3 bucks"]
24 | :checks [#clj-duckling/corpus "(money 3)"]}
25 | {:text ["£9" "nine pounds"]
26 | :checks [#clj-duckling/corpus "(money 9 \"£\")"]}
27 | {:text ["GBP3.01" "GBP 3.01"]
28 | :checks [#clj-duckling/corpus "(money 3.01 \"GBP\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/pt/rules/duration.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "segundo (unit-of-duration)", :pattern "#\"(?i)seg(undo)?s?\"", :production "{:dim :unit-of-duration, :grain :second}"}
2 | #clj-duckling.engine/rule {:name "minuto (unit-of-duration)", :pattern "#\"(?i)min(uto)?s?\"", :production "{:dim :unit-of-duration, :grain :minute}"}
3 | #clj-duckling.engine/rule {:name "hour (unit-of-duration)", :pattern "#\"(?i)h(ora)?s?\"", :production "{:dim :unit-of-duration, :grain :hour}"}
4 | #clj-duckling.engine/rule {:name "day (unit-of-duration)", :pattern "#\"(?i)d(í|i)as?\"", :production "{:dim :unit-of-duration, :grain :day}"}
5 | #clj-duckling.engine/rule {:name "week (unit-of-duration)", :pattern "#\"(?i)semanas?\"", :production "{:dim :unit-of-duration, :grain :week}"}
6 | #clj-duckling.engine/rule {:name "month (unit-of-duration)", :pattern "#\"(?i)m[eê]s(es)?\"", :production "{:dim :unit-of-duration, :grain :month}"}
7 | #clj-duckling.engine/rule {:name "year (unit-of-duration)", :pattern "#\"(?i)anos?\"", :production "{:dim :unit-of-duration, :grain :year}"}
8 | #clj-duckling.engine/rule {:name " ", :pattern "[(integer 0) (dim :unit-of-duration)]", :production "{:dim :duration, :value (duration (:grain %2) (:value %1))}"}
9 | #clj-duckling.engine/rule {:name "em ", :pattern "[#\"(?i)em\" (dim :duration)]", :production "(in-duration (:value %2))"}
10 | #clj-duckling.engine/rule {:name "fazem ", :pattern "[#\"faz(em)?\" (dim :duration)]", :production "(duration-ago (:value %2))"}]
--------------------------------------------------------------------------------
/resources/languages/nb/corpus/finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["$10" "10$" "ti dollar"]
4 | :checks [#clj-duckling/corpus "(money 10 \"$\")"]}
5 | {:text ["ti øre"]
6 | :checks [#clj-duckling/corpus "(money 10 \"øre\")"]}
7 | {:text ["$10.000" "10K$" "$10k"]
8 | :checks [#clj-duckling/corpus "(money 10000 \"$\")"]}
9 | {:text ["USD1,23"]
10 | :checks [#clj-duckling/corpus "(money 1.23 \"USD\")"]}
11 | {:text ["10kroner" "10kr" "ti kroner" "10 NOK"]
12 | :checks [#clj-duckling/corpus "(money 10 \"NOK\")"]}
13 | {:text ["2 kroner og 23 øre" "to kroner 23 øre" "to kroner og 23 øre"]
14 | :checks [#clj-duckling/corpus "(money 2.23 \"NOK\")"]}
15 | {:text ["20€" "20 euro" "20 Euro" "20 Euros" "EUR 20"]
16 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
17 | {:text ["EUR29,99"]
18 | :checks [#clj-duckling/corpus "(money 29.99 \"EUR\")"]}
19 | {:text ["Rs. 20" "Rs 20" "20 Rupees" "20Rs" "Rs20"]
20 | :checks [#clj-duckling/corpus "(money 20 \"INR\")"]}
21 | {:text ["20 Rupees 43" "tjue rupees 43"]
22 | :checks [#clj-duckling/corpus "(money 20.43 \"INR\")"]}
23 | {:text ["INR33"]
24 | :checks [#clj-duckling/corpus "(money 33 \"INR\")"]}
25 | {:text ["£9" "ni pund"]
26 | :checks [#clj-duckling/corpus "(money 9 \"£\")"]}
27 | {:text ["GBP3,01" "GBP 3,01"]
28 | :checks [#clj-duckling/corpus "(money 3.01 \"GBP\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/sv/corpus/finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["$10" "10$" "tio dollar"]
4 | :checks [#clj-duckling/corpus "(money 10 \"$\")"]}
5 | {:text ["tio öre"]
6 | :checks [#clj-duckling/corpus "(money 10 \"öre\")"]}
7 | {:text ["$10.000" "10K$" "$10k"]
8 | :checks [#clj-duckling/corpus "(money 10000 \"$\")"]}
9 | {:text ["USD1,23"]
10 | :checks [#clj-duckling/corpus "(money 1.23 \"USD\")"]}
11 | {:text ["10kronor" "10kr" "10 kr" "tio kronor" "10 SEK"]
12 | :checks [#clj-duckling/corpus "(money 10 \"SEK\")"]}
13 | {:text ["2 kronor och 23 öre" "två kronor 23 öre" "två kronor och 23 öre"]
14 | :checks [#clj-duckling/corpus "(money 2.23 \"SEK\")"]}
15 | {:text ["20€" "20 euro" "20 Euro" "20 Euros" "EUR 20"]
16 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
17 | {:text ["EUR29,99"]
18 | :checks [#clj-duckling/corpus "(money 29.99 \"EUR\")"]}
19 | {:text ["Rs. 20" "Rs 20" "20 Rupees" "20Rs" "Rs20"]
20 | :checks [#clj-duckling/corpus "(money 20 \"INR\")"]}
21 | {:text ["20 Rupees 43" "tjugo rupees 43"]
22 | :checks [#clj-duckling/corpus "(money 20.43 \"INR\")"]}
23 | {:text ["INR33"]
24 | :checks [#clj-duckling/corpus "(money 33 \"INR\")"]}
25 | {:text ["£9" "nio pund"]
26 | :checks [#clj-duckling/corpus "(money 9 \"£\")"]}
27 | {:text ["GBP3,01" "GBP 3,01"]
28 | :checks [#clj-duckling/corpus "(money 3.01 \"GBP\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/ja/rules/duration.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "second (unit-of-duration)", :pattern "#\"秒間?\"", :production "{:dim :unit-of-duration, :grain :second}"}
2 | #clj-duckling.engine/rule {:name "minute (unit-of-duration)", :pattern "#\"分間?\"", :production "{:dim :unit-of-duration, :grain :minute}"}
3 | #clj-duckling.engine/rule {:name "hour (unit-of-duration)", :pattern "#\"時間?\"", :production "{:dim :unit-of-duration, :grain :hour}"}
4 | #clj-duckling.engine/rule {:name "day (unit-of-duration)", :pattern "#\"日間?\"", :production "{:dim :unit-of-duration, :grain :day}"}
5 | #clj-duckling.engine/rule {:name "week (unit-of-duration)", :pattern "#\"週間?\"", :production "{:dim :unit-of-duration, :grain :week}"}
6 | #clj-duckling.engine/rule {:name "month (unit-of-duration)", :pattern "#\"月間?\"", :production "{:dim :unit-of-duration, :grain :month}"}
7 | #clj-duckling.engine/rule {:name "year (unit-of-duration)", :pattern "#\"年間?\"", :production "{:dim :unit-of-duration, :grain :year}"}
8 | #clj-duckling.engine/rule {:name " ", :pattern "[(integer 0) (dim :unit-of-duration)]", :production "{:dim :duration, :value (duration (:grain %2) (:value %1))}"}
9 | #clj-duckling.engine/rule {:name "in ", :pattern "[#\"再\" (dim :duration)]", :production "(in-duration (:value %2))"}
10 | #clj-duckling.engine/rule {:name " from now", :pattern "[(dim :duration) #\"後\"]", :production "(in-duration (:value %1))"}
11 | #clj-duckling.engine/rule {:name " ago", :pattern "[(dim :duration) #\"前\"]", :production "(duration-ago (:value %1))"}]
--------------------------------------------------------------------------------
/resources/languages/ga/corpus/finance.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["$10" "10$" "deich dollair"]
4 | :checks [#clj-duckling/corpus "(money 10 \"$\")"]}
5 | {:text ["deich ceinteanna"]
6 | :checks [#clj-duckling/corpus "(money 10 \"cent\")"]}
7 | {:text ["$10,000" "10K$" "$10k"]
8 | :checks [#clj-duckling/corpus "(money 10000 \"$\")"]}
9 | {:text ["€10,000" "10K€" "€10k"]
10 | :checks [#clj-duckling/corpus "(money 10000 \"EUR\")"]}
11 | {:text ["USD1.23"]
12 | :checks [#clj-duckling/corpus "(money 1.23 \"USD\")"]}
13 | {:text ["2 dhollair agus 23 ceinteanna" "dhá dhollair 23 ceinteanna" "2 dhollair 23" "dhá dhollair agus 23"]
14 | :checks [#clj-duckling/corpus "(money 2.23 \"$\")"]}
15 | {:text ["20€" "20 euros" "20 Euro" "20 Euros" "EUR 20"]
16 | :checks [#clj-duckling/corpus "(money 20 \"EUR\")"]}
17 | {:text ["EUR29.99"]
18 | :checks [#clj-duckling/corpus "(money 29.99 \"EUR\")"]}
19 | {:text ["Rs. 20" "Rs 20" "20 Rúpaí" "20Rs" "Rs20"]
20 | :checks [#clj-duckling/corpus "(money 20 \"INR\")"]}
21 | {:text ["20 Rupees 43" "fiche rúpaí 43"]
22 | :checks [#clj-duckling/corpus "(money 20.43 \"INR\")"]}
23 | {:text ["INR33"]
24 | :checks [#clj-duckling/corpus "(money 33 \"INR\")"]}
25 | {:text ["£9" "naoi bpunt"]
26 | :checks [#clj-duckling/corpus "(money 9 \"£\")"]}
27 | {:text ["GBP3.01" "GBP 3.01"]
28 | :checks [#clj-duckling/corpus "(money 3.01 \"GBP\")"]}]}
--------------------------------------------------------------------------------
/docs/api/css/highlight.css:
--------------------------------------------------------------------------------
1 | /*
2 | github.com style (c) Vasily Polovnyov
3 | */
4 |
5 | .hljs {
6 | display: block;
7 | overflow-x: auto;
8 | padding: 0.5em;
9 | color: #333;
10 | background: #f8f8f8;
11 | }
12 |
13 | .hljs-comment,
14 | .hljs-quote {
15 | color: #998;
16 | font-style: italic;
17 | }
18 |
19 | .hljs-keyword,
20 | .hljs-selector-tag,
21 | .hljs-subst {
22 | color: #333;
23 | font-weight: bold;
24 | }
25 |
26 | .hljs-number,
27 | .hljs-literal,
28 | .hljs-variable,
29 | .hljs-template-variable,
30 | .hljs-tag .hljs-attr {
31 | color: #008080;
32 | }
33 |
34 | .hljs-string,
35 | .hljs-doctag {
36 | color: #d14;
37 | }
38 |
39 | .hljs-title,
40 | .hljs-section,
41 | .hljs-selector-id {
42 | color: #900;
43 | font-weight: bold;
44 | }
45 |
46 | .hljs-subst {
47 | font-weight: normal;
48 | }
49 |
50 | .hljs-type,
51 | .hljs-class .hljs-title {
52 | color: #458;
53 | font-weight: bold;
54 | }
55 |
56 | .hljs-tag,
57 | .hljs-name,
58 | .hljs-attribute {
59 | color: #000080;
60 | font-weight: normal;
61 | }
62 |
63 | .hljs-regexp,
64 | .hljs-link {
65 | color: #009926;
66 | }
67 |
68 | .hljs-symbol,
69 | .hljs-bullet {
70 | color: #990073;
71 | }
72 |
73 | .hljs-built_in,
74 | .hljs-builtin-name {
75 | color: #0086b3;
76 | }
77 |
78 | .hljs-meta {
79 | color: #999;
80 | font-weight: bold;
81 | }
82 |
83 | .hljs-deletion {
84 | background: #fdd;
85 | }
86 |
87 | .hljs-addition {
88 | background: #dfd;
89 | }
90 |
91 | .hljs-emphasis {
92 | font-style: italic;
93 | }
94 |
95 | .hljs-strong {
96 | font-weight: bold;
97 | }
98 |
--------------------------------------------------------------------------------
/resources/languages/it/rules/communication.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "phone number", :pattern "#\"(?i)(\\+?[0-9\\(][0-9\\- \\(\\)\\.]{6,16}( ?e?xt?\\.? ?\\d+)?)\"", :production "{:dim :phone-number, :value (-> %1 :groups first)}"}
2 | #clj-duckling.engine/rule {:name "phone number given by each number", :pattern "[(integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9)]", :production "{:dim :phone-number, :value (clojure.string/join \"\" [(:value %1) (:value %2) (:value %3) (:value %4) (:value %5) (:value %6) (:value %7) (:value %8) (:value %9) (:value %10)])}"}
3 | #clj-duckling.engine/rule {:name "url", :pattern "#\"(\\b(? %1 :groups first)}"}
4 | #clj-duckling.engine/rule {:name "localhost url", :pattern "#\"((https?://)?localhost(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
5 | #clj-duckling.engine/rule {:name "local url", :pattern "#\"((https?://)\\w+(:\\d+)?[^ ]*)\"", :production "{:dim :url, :value (-> %1 :groups first)}"}
6 | #clj-duckling.engine/rule {:name "email", :pattern "#\"([\\w\\.\\-_]+ chiocciola ([\\w\\-_]+\\.)+\\w+)\"", :production "{:dim :email, :value (clojure.string/replace (-> %1 :groups first) #\" chiocciola \" \"@\")}"}
7 | #clj-duckling.engine/rule {:name "email", :pattern "#\"([\\w\\.\\-_]+@([\\w\\-_]+\\.)+\\w+)\"", :production "{:dim :email, :value (-> %1 :groups first)}"}]
--------------------------------------------------------------------------------
/resources/languages/zh/rules/duration.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "second (unit-of-duration)", :pattern "#\"秒[钟|鐘]?\"", :production "{:dim :unit-of-duration, :grain :second}"}
2 | #clj-duckling.engine/rule {:name "minute (unit-of-duration)", :pattern "#\"分[钟|鐘]?\"", :production "{:dim :unit-of-duration, :grain :minute}"}
3 | #clj-duckling.engine/rule {:name "hour (unit-of-duration)", :pattern "#\"小时|小時\"", :production "{:dim :unit-of-duration, :grain :hour}"}
4 | #clj-duckling.engine/rule {:name "day (unit-of-duration)", :pattern "#\"天\"", :production "{:dim :unit-of-duration, :grain :day}"}
5 | #clj-duckling.engine/rule {:name "week (unit-of-duration)", :pattern "#\"周|週|礼拜|禮拜\"", :production "{:dim :unit-of-duration, :grain :week}"}
6 | #clj-duckling.engine/rule {:name "month (unit-of-duration)", :pattern "#\"月\"", :production "{:dim :unit-of-duration, :grain :month}"}
7 | #clj-duckling.engine/rule {:name "year (unit-of-duration)", :pattern "#\"年(?=[前|后|後])\"", :production "{:dim :unit-of-duration, :grain :year}"}
8 | #clj-duckling.engine/rule {:name " ", :pattern "[(integer 0) (dim :unit-of-duration)]", :production "{:dim :duration, :value (duration (:grain %2) (:value %1))}"}
9 | #clj-duckling.engine/rule {:name "in ", :pattern "[#\"再\" (dim :duration)]", :production "(in-duration (:value %2))"}
10 | #clj-duckling.engine/rule {:name " from now", :pattern "[(dim :duration) #\"后|後\"]", :production "(in-duration (:value %1))"}
11 | #clj-duckling.engine/rule {:name " ago", :pattern "[(dim :duration) #\"前\"]", :production "(duration-ago (:value %1))"}]
--------------------------------------------------------------------------------
/resources/languages/ro/corpus/time.edn:
--------------------------------------------------------------------------------
1 | {:context {:reference-time #clj-duckling/time "(t -2 2013 2 12 4 30 0)", :min #clj-duckling/time "(t -2 1900)", :max #clj-duckling/time "(t -2 2100)"}
2 |
3 | :tests [{:text ["acum" "chiar acum"]
4 | :checks [#clj-duckling/corpus "(datetime 2013 2 12 4 30 0)"]}
5 | {:text ["azi" "astazi" "astăzi"]
6 | :checks [#clj-duckling/corpus "(datetime 2013 2 12)"]}
7 | {:text ["ieri"]
8 | :checks [#clj-duckling/corpus "(datetime 2013 2 11)"]}
9 | {:text ["maine" "mâine"]
10 | :checks [#clj-duckling/corpus "(datetime 2013 2 13)"]}
11 | {:text ["luni" "lunea asta" "lunea aceasta"]
12 | :checks [#clj-duckling/corpus "(datetime 2013 2 18 :day-of-week 1)"]}
13 | {:text ["Luni, 18 Feb" "Luni, 18 Februarie"]
14 | :checks [#clj-duckling/corpus "(datetime 2013 2 18 :day-of-week 1 :day 18 :month 2)"]}
15 | {:text ["marti" "marți" "Marti 19" "Marti pe 19" "Marți 19"]
16 | :checks [#clj-duckling/corpus "(datetime 2013 2 19)"]}
17 | {:text ["joi" "joia"]
18 | :checks [#clj-duckling/corpus "(datetime 2013 2 14)"]}
19 | {:text ["vineri"]
20 | :checks [#clj-duckling/corpus "(datetime 2013 2 15)"]}
21 | {:text ["sambata" "sâmbătă" "sam"]
22 | :checks [#clj-duckling/corpus "(datetime 2013 2 16)"]}
23 | {:text ["duminica" "duminică"]
24 | :checks [#clj-duckling/corpus "(datetime 2013 2 17)"]}
25 | {:text ["1 martie" "intai martie"]
26 | :checks [#clj-duckling/corpus "(datetime 2013 3 1 :day 1 :month 3)"]}]}
--------------------------------------------------------------------------------
/resources/languages/he/corpus/number.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "אפס"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "אחד" "אחת" "יחיד"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["2" "שתיים" "שניים" "זוג"]
8 | :checks [#clj-duckling/corpus "(number 2)"]}
9 | {:text ["33" "שלושים ושלוש" "שלושים ושלושה" "0033"]
10 | :checks [#clj-duckling/corpus "(number 33)"]}
11 | {:text ["14" "ארבעה עשר" "ארבע עשרה"]
12 | :checks [#clj-duckling/corpus "(number 14)"]}
13 | {:text ["16" "ששה עשר" "שש עשרה"]
14 | :checks [#clj-duckling/corpus "(number 16)"]}
15 | {:text ["17" "שבעה עשר" "שבע עשרה"]
16 | :checks [#clj-duckling/corpus "(number 17)"]}
17 | {:text ["18" "שמונה עשר" "שמונה עשרה"]
18 | :checks [#clj-duckling/corpus "(number 18)"]}
19 | {:text ["1.1" "1.10" "01.10"]
20 | :checks [#clj-duckling/corpus "(number 1.1)"]}
21 | {:text ["0.77" ".77"]
22 | :checks [#clj-duckling/corpus "(number 0.77)"]}
23 | {:text ["100,000" "100000"]
24 | :checks [#clj-duckling/corpus "(number 100000)"]}
25 | {:text ["3000000" "3,000,000"]
26 | :checks [#clj-duckling/corpus "(number 3000000)"]}
27 | {:text ["1,200,000" "1200000"]
28 | :checks [#clj-duckling/corpus "(number 1200000)"]}
29 | {:text ["- 1,200,000" "-1200000" "מינוס 1,200,000"]
30 | :checks [#clj-duckling/corpus "(number -1200000)"]}
31 | {:text ["ארבעה"]
32 | :checks [#clj-duckling/corpus "(ordinal 4)"]}]}
--------------------------------------------------------------------------------
/resources/languages/he/corpus/numbers.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "אפס"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "אחד" "אחת" "יחיד"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["2" "שתיים" "שניים" "זוג"]
8 | :checks [#clj-duckling/corpus "(number 2)"]}
9 | {:text ["33" "שלושים ושלוש" "שלושים ושלושה" "0033"]
10 | :checks [#clj-duckling/corpus "(number 33)"]}
11 | {:text ["14" "ארבעה עשר" "ארבע עשרה"]
12 | :checks [#clj-duckling/corpus "(number 14)"]}
13 | {:text ["16" "ששה עשר" "שש עשרה"]
14 | :checks [#clj-duckling/corpus "(number 16)"]}
15 | {:text ["17" "שבעה עשר" "שבע עשרה"]
16 | :checks [#clj-duckling/corpus "(number 17)"]}
17 | {:text ["18" "שמונה עשר" "שמונה עשרה"]
18 | :checks [#clj-duckling/corpus "(number 18)"]}
19 | {:text ["1.1" "1.10" "01.10"]
20 | :checks [#clj-duckling/corpus "(number 1.1)"]}
21 | {:text ["0.77" ".77"]
22 | :checks [#clj-duckling/corpus "(number 0.77)"]}
23 | {:text ["100,000" "100000"]
24 | :checks [#clj-duckling/corpus "(number 100000)"]}
25 | {:text ["3000000" "3,000,000"]
26 | :checks [#clj-duckling/corpus "(number 3000000)"]}
27 | {:text ["1,200,000" "1200000"]
28 | :checks [#clj-duckling/corpus "(number 1200000)"]}
29 | {:text ["- 1,200,000" "-1200000" "מינוס 1,200,000"]
30 | :checks [#clj-duckling/corpus "(number -1200000)"]}
31 | {:text ["ארבעה"]
32 | :checks [#clj-duckling/corpus "(ordinal 4)"]}]}
--------------------------------------------------------------------------------
/resources/languages/ro/rules/communication.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "phone number",
2 | :pattern "#\"(?i)(\\+?[0-9\\(][0-9\\- \\(\\)\\.]{6,16}( ?(int|ext)?\\.? ?\\d+)?)\"",
3 | :production "{:dim :phone-number, :value (-> %1 :groups first)}"}
4 | #clj-duckling.engine/rule {:name "phone number given by each number",
5 | :pattern "[(integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9)]",
6 | :production "{:dim :phone-number, :value (clojure.string/join \"\" [(:value %1) (:value %2) (:value %3) (:value %4) (:value %5) (:value %6) (:value %7) (:value %8) (:value %9) (:value %10)])}"}
7 | #clj-duckling.engine/rule {:name "url",
8 | :pattern "#\"((https?://)?(\\w+\\.)+\\w{2,4}(:\\d+)?[^ ]*)\"",
9 | :production "{:dim :url, :value (-> %1 :groups first)}"}
10 | #clj-duckling.engine/rule {:name "localhost url",
11 | :pattern "#\"((https?://)?localhost(:\\d+)?[^ ]*)\"",
12 | :production "{:dim :url, :value (-> %1 :groups first)}"}
13 | #clj-duckling.engine/rule {:name "local url",
14 | :pattern "#\"((https?://)\\w+(:\\d+)?[^ ]*)\"",
15 | :production "{:dim :url, :value (-> %1 :groups first)}"}
16 | #clj-duckling.engine/rule {:name "email",
17 | :pattern "#\"([\\w\\.]+@[\\w\\.]+)\"",
18 | :production "{:dim :email, :value (-> %1 :groups first)}"}]
19 |
--------------------------------------------------------------------------------
/bin/convert-rules.clj:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env inlein
2 |
3 | ;; syntax: convert-rules dirpath
4 |
5 | '{:dependencies [[org.clojure/clojure "1.9.0-RC1"]
6 | [cljfmt "0.5.7"]]}
7 |
8 | (require '[clojure.java.io :as io])
9 | (require '[clojure.string :as str])
10 | (require '[clojure.pprint :as pp])
11 | (require '[cljfmt.core :refer [reformat-string]])
12 |
13 |
14 |
15 | (defn build-rule [[name pattern production]]
16 | {:name name
17 | :pattern (pr-str pattern)
18 | :production (pr-str production)})
19 |
20 | (defn convert-file
21 | [infile outfile]
22 | (let [items (->> (read-string (slurp infile))
23 | (partition 3)
24 | (map build-rule))]
25 | (with-open [w (io/writer outfile)]
26 | (.write w "[\n")
27 | (doseq [item items]
28 | ;; (printf "item: %s\n" item)
29 | (.write w "#clj-duckling.engine/rule ")
30 | (.write w (prn-str item)))
31 | (.write w "]"))
32 | (spit outfile (reformat-string (slurp outfile)))))
33 |
34 |
35 | (defn convert-dir
36 | [dirpath]
37 | (let [grammar-matcher (.getPathMatcher
38 | (java.nio.file.FileSystems/getDefault)
39 | "glob:*.{clj}")
40 | files (->> dirpath
41 | io/file
42 | file-seq
43 | (filter #(.isFile %))
44 | (filter #(.matches grammar-matcher (.getFileName (.toPath %))))
45 | (map #(.getAbsolutePath %)))]
46 | (doseq [f files]
47 | (pp/pprint f)
48 | (convert-file f (str/replace f #"\.clj" ".edn")))))
49 |
50 |
51 | (convert-dir (first *command-line-args*))
52 |
--------------------------------------------------------------------------------
/resources/languages/da/corpus/number.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "nul"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "én" "en" "ét" "et"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["2" "to" "et par"]
8 | :checks [#clj-duckling/corpus "(number 2)"]}
9 | {:text ["14" "fjorten"]
10 | :checks [#clj-duckling/corpus "(number 14)"]}
11 | {:text ["16" "seksten"]
12 | :checks [#clj-duckling/corpus "(number 16)"]}
13 | {:text ["17" "sytten"]
14 | :checks [#clj-duckling/corpus "(number 17)"]}
15 | {:text ["18" "atten"]
16 | :checks [#clj-duckling/corpus "(number 18)"]}
17 | {:text ["1,1" "1,10" "01,10"]
18 | :checks [#clj-duckling/corpus "(number 1.1)"]}
19 | {:text ["0,77" ",77"]
20 | :checks [#clj-duckling/corpus "(number 0.77)"]}
21 | {:text ["100.000" "100000" "100K" "100k"]
22 | :checks [#clj-duckling/corpus "(number 100000)"]}
23 | {:text ["3M" "3000K" "3000000" "3.000.000"]
24 | :checks [#clj-duckling/corpus "(number 3000000)"]}
25 | {:text ["1.200.000" "1200000" "1,2M" "1200K" ",0012G"]
26 | :checks [#clj-duckling/corpus "(number 1200000)"]}
27 | {:text ["- 1.200.000" "-1200000" "minus 1.200.000" "negativ 1200000" "-1,2M" "-1200K" "-,0012G"]
28 | :checks [#clj-duckling/corpus "(number -1200000)"]}
29 | {:text ["5 tusind" "fem tusinde" "fem tusind"]
30 | :checks [#clj-duckling/corpus "(number 5000)"]}
31 | {:text ["4." "fjerde"]
32 | :checks [#clj-duckling/corpus "(ordinal 4)"]}]}
--------------------------------------------------------------------------------
/resources/languages/da/corpus/numbers.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "nul"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "én" "en" "ét" "et"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["2" "to" "et par"]
8 | :checks [#clj-duckling/corpus "(number 2)"]}
9 | {:text ["14" "fjorten"]
10 | :checks [#clj-duckling/corpus "(number 14)"]}
11 | {:text ["16" "seksten"]
12 | :checks [#clj-duckling/corpus "(number 16)"]}
13 | {:text ["17" "sytten"]
14 | :checks [#clj-duckling/corpus "(number 17)"]}
15 | {:text ["18" "atten"]
16 | :checks [#clj-duckling/corpus "(number 18)"]}
17 | {:text ["1,1" "1,10" "01,10"]
18 | :checks [#clj-duckling/corpus "(number 1.1)"]}
19 | {:text ["0,77" ",77"]
20 | :checks [#clj-duckling/corpus "(number 0.77)"]}
21 | {:text ["100.000" "100000" "100K" "100k"]
22 | :checks [#clj-duckling/corpus "(number 100000)"]}
23 | {:text ["3M" "3000K" "3000000" "3.000.000"]
24 | :checks [#clj-duckling/corpus "(number 3000000)"]}
25 | {:text ["1.200.000" "1200000" "1,2M" "1200K" ",0012G"]
26 | :checks [#clj-duckling/corpus "(number 1200000)"]}
27 | {:text ["- 1.200.000" "-1200000" "minus 1.200.000" "negativ 1200000" "-1,2M" "-1200K" "-,0012G"]
28 | :checks [#clj-duckling/corpus "(number -1200000)"]}
29 | {:text ["5 tusind" "fem tusinde" "fem tusind"]
30 | :checks [#clj-duckling/corpus "(number 5000)"]}
31 | {:text ["4." "fjerde"]
32 | :checks [#clj-duckling/corpus "(ordinal 4)"]}]}
--------------------------------------------------------------------------------
/resources/languages/hr/corpus/measure.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["3 kilometra" "3 km" "3km" "3k"]
4 | :checks [#clj-duckling/corpus "(distance 3 \"kilometre\" {:value 3000, :unit \"metre\"})"]}
5 | {:text ["3,0 km"]
6 | :checks [#clj-duckling/corpus "(distance 3.0 \"kilometre\" {:value 3000.0, :unit \"metre\"})"]}
7 | {:text ["8 milja"]
8 | :checks [#clj-duckling/corpus "(distance 8 \"mile\" {:value 12872, :unit \"metre\"})"]}
9 | {:text ["9m"]
10 | :checks [#clj-duckling/corpus "(distance 9 \"m\")"]}
11 | {:text ["2cm" "2 centimetra"]
12 | :checks [#clj-duckling/corpus "(distance 2 \"centimetre\" {:value 0.02, :unit \"metre\"})"]}
13 | {:text ["250 mililitara" "250ml" "250 ml"]
14 | :checks [#clj-duckling/corpus "(volume 250 \"millilitre\" {:value 0.25, :unit \"litre\"})"]}
15 | {:text ["2 litre"]
16 | :checks [#clj-duckling/corpus "(volume 2 \"litre\")"]}
17 | {:text ["3 galona" "3 gal"]
18 | :checks [#clj-duckling/corpus "(volume 3 \"gallon\" {:value 11.355, :unit \"litre\"})"]}
19 | {:text ["3 hektolitra"]
20 | :checks [#clj-duckling/corpus "(volume 300 \"litre\" {:value 30, :unit \"litre\"})"]}
21 | {:text ["pola litre"]
22 | :checks [#clj-duckling/corpus "(volume 0.5 \"litre\")"]}
23 | {:text ["dvije kile mesa" "dva kilograma mesa"]
24 | :checks [#clj-duckling/corpus "(quantity 2 \"kilogram\" \"meso\")"]}
25 | {:text ["kila" "kilogram" "kg"]
26 | :checks [#clj-duckling/corpus "(quantity 1 \"kilogram\")"]}
27 | {:text ["meso"]
28 | :checks [#clj-duckling/corpus "(quantity 1 nil \"meso\")"]}]}
--------------------------------------------------------------------------------
/dev/resources/dev.edn:
--------------------------------------------------------------------------------
1 | {
2 | :clj-duckling.tool/duckling {:id "dev-tool"
3 | :model #ig/ref :clj-duckling.model/classifier
4 | :rules #ig/ref :clj-duckling.engine/edn
5 | :logger #ig/ref :duct.logger/timbre}
6 |
7 |
8 | :clj-duckling.model/classifier {:id "dev-classifier"
9 | :language "ro"
10 | :binfile "test/classifier.bin"
11 | :loadbin? false
12 | :corpus #ig/ref :clj-duckling.corpus/edn
13 | :rules #ig/ref :clj-duckling.engine/edn
14 | :logger #ig/ref :duct.logger/timbre}
15 |
16 |
17 | :clj-duckling.corpus/edn {:id "dev-corpus-edn"
18 | :language "ro"
19 | :dirpath "resources/languages/ro/corpus"
20 | :logger #ig/ref :duct.logger/timbre}
21 |
22 | :clj-duckling.engine/edn {:id "dev-rules-edn"
23 | :language "ro"
24 | :dirpath "resources/languages/ro/rules"
25 | :logger #ig/ref :duct.logger/timbre}
26 |
27 |
28 | :duct.logger/timbre {:level :debug
29 | :set-root-config? true
30 | :appenders {:duct.logger.timbre/spit #ig/ref :duct.logger.timbre/spit,
31 | :duct.logger.timbre/brief #ig/ref :duct.logger.timbre/brief}},
32 |
33 |
34 | :duct.logger.timbre/println {}
35 | :duct.logger.timbre/brief {:min-level :report},
36 | :duct.logger.timbre/spit {:fname "logs/dev.log" :min-level :debug}
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/resources/languages/ro/corpus/measure.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["3 kilometri" "3 km" "3km"]
4 | :checks [#clj-duckling/corpus "(distance 3 \"kilometru\" {:value 3000, :unit \"metru\"})"]}
5 | {:text ["3,0 km"]
6 | :checks [#clj-duckling/corpus "(distance 3.0 \"kilometru\" {:value 3000.0, :unit \"metru\"})"]}
7 | {:text ["8 mile"]
8 | :checks [#clj-duckling/corpus "(distance 8 \"mile\" {:value 12872, :unit \"metru\"})"]}
9 | {:text ["9m" "9 m"]
10 | :checks [#clj-duckling/corpus "(distance 9 \"metru\")"]}
11 | {:text ["2cm" "2 centimetri"]
12 | :checks [#clj-duckling/corpus "(distance 2 \"centimetru\" {:value 0.02, :unit \"metru\"})"]}
13 | {:text ["250 mililitri" "250ml" "250 ml"]
14 | :checks [#clj-duckling/corpus "(volume 250 \"mililitru\" {:value 0.25, :unit \"litru\"})"]}
15 | {:text ["2 litri" "2 l" "2l"]
16 | :checks [#clj-duckling/corpus "(volume 2 \"litru\")"]}
17 | {:text ["3 galoane" "3 gal"]
18 | :checks [#clj-duckling/corpus "(volume 3 \"galon\" {:value 11.355, :unit \"litru\"})"]}
19 | {:text ["3 hectolitri"]
20 | :checks [#clj-duckling/corpus "(volume 300 \"litru\" {:value 30, :unit \"litru\"})"]}
21 | {:text ["jumatate de litru" "jumătate de litru"]
22 | :checks [#clj-duckling/corpus "(volume 0.5 \"litru\")"]}
23 | {:text ["doua livre de carne"]
24 | :checks [#clj-duckling/corpus "(quantity 2 \"livra\" \"carne\")"]}
25 | {:text ["o livră"]
26 | :checks [#clj-duckling/corpus "(quantity 1 \"livra\")"]}
27 | {:text ["o carne"]
28 | :checks [#clj-duckling/corpus "(quantity 1 nil \"carne\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/nl/corpus/number.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "nul" "geen" "niks"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "een" "één"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["2" "twee"]
8 | :checks [#clj-duckling/corpus "(number 2)"]}
9 | {:text ["33" "3 en 30" "drieendertig" "drieëndertig" "drie en dertig" "0033"]
10 | :checks [#clj-duckling/corpus "(number 33)"]}
11 | {:text ["14" "veertien"]
12 | :checks [#clj-duckling/corpus "(number 14)"]}
13 | {:text ["16" "zestien"]
14 | :checks [#clj-duckling/corpus "(number 16)"]}
15 | {:text ["17" "zeventien"]
16 | :checks [#clj-duckling/corpus "(number 17)"]}
17 | {:text ["18" "achtien"]
18 | :checks [#clj-duckling/corpus "(number 18)"]}
19 | {:text ["1,1" "1,10" "01,10"]
20 | :checks [#clj-duckling/corpus "(number 1.1)"]}
21 | {:text ["0,77" ",77"]
22 | :checks [#clj-duckling/corpus "(number 0.77)"]}
23 | {:text ["3 honderd" "drie honderd"]
24 | :checks [#clj-duckling/corpus "(number 300)"]}
25 | {:text ["5 duizend" "vijf duizend"]
26 | :checks [#clj-duckling/corpus "(number 5000)"]}
27 | {:text ["honderd tweeëntwintig" "honderd tweeentwintig" "honderd twee en twintig"]
28 | :checks [#clj-duckling/corpus "(number 122)"]}
29 | {:text ["twintig duizend"]
30 | :checks [#clj-duckling/corpus "(number 20000)"]}
31 | {:text ["1ste" "eerste"]
32 | :checks [#clj-duckling/corpus "(ordinal 1)"]}
33 | {:text ["4de" "vierde"]
34 | :checks [#clj-duckling/corpus "(ordinal 4)"]}]}
--------------------------------------------------------------------------------
/resources/languages/nl/corpus/numbers.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "nul" "geen" "niks"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "een" "één"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["2" "twee"]
8 | :checks [#clj-duckling/corpus "(number 2)"]}
9 | {:text ["33" "3 en 30" "drieendertig" "drieëndertig" "drie en dertig" "0033"]
10 | :checks [#clj-duckling/corpus "(number 33)"]}
11 | {:text ["14" "veertien"]
12 | :checks [#clj-duckling/corpus "(number 14)"]}
13 | {:text ["16" "zestien"]
14 | :checks [#clj-duckling/corpus "(number 16)"]}
15 | {:text ["17" "zeventien"]
16 | :checks [#clj-duckling/corpus "(number 17)"]}
17 | {:text ["18" "achtien"]
18 | :checks [#clj-duckling/corpus "(number 18)"]}
19 | {:text ["1,1" "1,10" "01,10"]
20 | :checks [#clj-duckling/corpus "(number 1.1)"]}
21 | {:text ["0,77" ",77"]
22 | :checks [#clj-duckling/corpus "(number 0.77)"]}
23 | {:text ["3 honderd" "drie honderd"]
24 | :checks [#clj-duckling/corpus "(number 300)"]}
25 | {:text ["5 duizend" "vijf duizend"]
26 | :checks [#clj-duckling/corpus "(number 5000)"]}
27 | {:text ["honderd tweeëntwintig" "honderd tweeentwintig" "honderd twee en twintig"]
28 | :checks [#clj-duckling/corpus "(number 122)"]}
29 | {:text ["twintig duizend"]
30 | :checks [#clj-duckling/corpus "(number 20000)"]}
31 | {:text ["1ste" "eerste"]
32 | :checks [#clj-duckling/corpus "(ordinal 1)"]}
33 | {:text ["4de" "vierde"]
34 | :checks [#clj-duckling/corpus "(ordinal 4)"]}]}
--------------------------------------------------------------------------------
/resources/languages/sv/corpus/number.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "noll"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "en" "ett"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["2" "två" "ett par"]
8 | :checks [#clj-duckling/corpus "(number 2)"]}
9 | {:text ["7" "sju"]
10 | :checks [#clj-duckling/corpus "(number 7)"]}
11 | {:text ["14" "fjorton"]
12 | :checks [#clj-duckling/corpus "(number 14)"]}
13 | {:text ["16" "sexton"]
14 | :checks [#clj-duckling/corpus "(number 16)"]}
15 | {:text ["17" "sjutton"]
16 | :checks [#clj-duckling/corpus "(number 17)"]}
17 | {:text ["18" "arton"]
18 | :checks [#clj-duckling/corpus "(number 18)"]}
19 | {:text ["20" "tjugo"]
20 | :checks [#clj-duckling/corpus "(number 20)"]}
21 | {:text ["1,1" "1,10" "01,10"]
22 | :checks [#clj-duckling/corpus "(number 1.1)"]}
23 | {:text ["0,77" ",77"]
24 | :checks [#clj-duckling/corpus "(number 0.77)"]}
25 | {:text ["100.000" "100000" "100K" "100k"]
26 | :checks [#clj-duckling/corpus "(number 100000)"]}
27 | {:text ["3M" "3000K" "3000000" "3.000.000"]
28 | :checks [#clj-duckling/corpus "(number 3000000)"]}
29 | {:text ["1.200.000" "1200000" "1,2M" "1200K" ",0012G"]
30 | :checks [#clj-duckling/corpus "(number 1200000)"]}
31 | {:text ["- 1.200.000" "-1200000" "minus 1.200.000" "negativ 1200000" "-1,2M" "-1200K" "-,0012G"]
32 | :checks [#clj-duckling/corpus "(number -1200000)"]}
33 | {:text ["5 tusen" "fem tusen"]
34 | :checks [#clj-duckling/corpus "(number 5000)"]}]}
--------------------------------------------------------------------------------
/resources/languages/sv/corpus/numbers.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "noll"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "en" "ett"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["2" "två" "ett par"]
8 | :checks [#clj-duckling/corpus "(number 2)"]}
9 | {:text ["7" "sju"]
10 | :checks [#clj-duckling/corpus "(number 7)"]}
11 | {:text ["14" "fjorton"]
12 | :checks [#clj-duckling/corpus "(number 14)"]}
13 | {:text ["16" "sexton"]
14 | :checks [#clj-duckling/corpus "(number 16)"]}
15 | {:text ["17" "sjutton"]
16 | :checks [#clj-duckling/corpus "(number 17)"]}
17 | {:text ["18" "arton"]
18 | :checks [#clj-duckling/corpus "(number 18)"]}
19 | {:text ["20" "tjugo"]
20 | :checks [#clj-duckling/corpus "(number 20)"]}
21 | {:text ["1,1" "1,10" "01,10"]
22 | :checks [#clj-duckling/corpus "(number 1.1)"]}
23 | {:text ["0,77" ",77"]
24 | :checks [#clj-duckling/corpus "(number 0.77)"]}
25 | {:text ["100.000" "100000" "100K" "100k"]
26 | :checks [#clj-duckling/corpus "(number 100000)"]}
27 | {:text ["3M" "3000K" "3000000" "3.000.000"]
28 | :checks [#clj-duckling/corpus "(number 3000000)"]}
29 | {:text ["1.200.000" "1200000" "1,2M" "1200K" ",0012G"]
30 | :checks [#clj-duckling/corpus "(number 1200000)"]}
31 | {:text ["- 1.200.000" "-1200000" "minus 1.200.000" "negativ 1200000" "-1,2M" "-1200K" "-,0012G"]
32 | :checks [#clj-duckling/corpus "(number -1200000)"]}
33 | {:text ["5 tusen" "fem tusen"]
34 | :checks [#clj-duckling/corpus "(number 5000)"]}]}
--------------------------------------------------------------------------------
/resources/languages/en/rules/communication.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "phone number",
2 | :pattern "#\"(?i)(\\+?[0-9\\(][0-9\\- \\(\\)\\.]{6,16}( ?e?xt?\\.? ?\\d+)?)\"",
3 | :production "{:dim :phone-number, :value (-> %1 :groups first)}"}
4 | #clj-duckling.engine/rule {:name "phone number given by each number",
5 | :pattern "[(integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9) (integer 0 9)]",
6 | :production "{:dim :phone-number, :value (clojure.string/join \"\" [(:value %1) (:value %2) (:value %3) (:value %4) (:value %5) (:value %6) (:value %7) (:value %8) (:value %9) (:value %10)])}"}
7 | #clj-duckling.engine/rule {:name "url",
8 | :pattern "#\"(\\b(? %1 :groups first)}"}
10 | #clj-duckling.engine/rule {:name "localhost url",
11 | :pattern "#\"((https?://)?localhost(:\\d+)?[^ ]*)\"",
12 | :production "{:dim :url, :value (-> %1 :groups first)}"}
13 | #clj-duckling.engine/rule {:name "local url",
14 | :pattern "#\"((https?://)\\w+(:\\d+)?[^ ]*)\"",
15 | :production "{:dim :url, :value (-> %1 :groups first)}"}
16 | #clj-duckling.engine/rule {:name "email",
17 | :pattern "#\"([\\w\\.\\-_]+@[\\w\\.\\-_]+)\"",
18 | :production "{:dim :email, :value (-> %1 :groups first)}"}]
19 |
--------------------------------------------------------------------------------
/.build.el:
--------------------------------------------------------------------------------
1 | ;; project settings
2 | (setq ent-project-home (file-name-directory (if load-file-name load-file-name buffer-file-name)))
3 | (setq ent-project-name "clj-duckling")
4 | (setq ent-clean-regexp "~$\\|\\.tex$")
5 | (setq ent-project-config-filename "CljDuckling.org")
6 |
7 | ;; local functions
8 |
9 | (defvar project-version)
10 |
11 | (setq project-version (ent-get-version))
12 |
13 |
14 | ;; tasks
15 |
16 | (load ent-init-file)
17 |
18 | (task 'org2md '() "convert org doc to md" '(lambda (&optional x) "cd docs; make all; cd .."))
19 |
20 | (task 'api '() "build the API documentation" '(lambda (&optional x) "lein codox"))
21 |
22 | (task 'tags '() "(re)generate tags file" '(lambda (&optional x) "lein codeindex"))
23 |
24 | (task 'doc '(org2md api) "build the project documentation" '(lambda (&optional x) "ls docs"))
25 |
26 | (task 'format '() "format the project" '(lambda (&optional x) "lein cljfmt fix"))
27 |
28 | (task 'check '() "check the project" '(lambda (&optional x) "lein with-profile +check do check, kibit, eastwood"))
29 |
30 | (task 'tree '() "tree dependencies" '(lambda (&optional x) "lein do clean, deps :tree"))
31 |
32 | (task 'tests '() "run tests" '(lambda (&optional x) "lein test"))
33 |
34 | (task 'cov '() "coverage" '(lambda (&optional x) "lein cloverage"))
35 |
36 | (task 'libupdate () "update project libraries" '(lambda (&optional x) "lein ancient :no-colors"))
37 |
38 | (task 'package '() "package the library" '(lambda (&optional x) "lein do clean, uberjar"))
39 |
40 | (task 'install '() "install in local .m2" '(lambda (&optional x) "lein do pom, jar, install"))
41 |
42 | (task 'deploy '() "deploy to clojars" '(lambda (&optional x) "lein deploy clojars"))
43 |
44 |
45 | ;; Local Variables:
46 | ;; no-byte-compile: t
47 | ;; no-update-autoloads: t
48 | ;; End:
49 |
--------------------------------------------------------------------------------
/resources/languages/en/corpus/measure.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["3 kilometers" "3 km" "3km" "3k"]
4 | :checks [#clj-duckling/corpus "(distance 3 \"kilometre\" {:value 3000, :unit \"metre\"})"]}
5 | {:text ["3.0 km"]
6 | :checks [#clj-duckling/corpus "(distance 3.0 \"kilometre\" {:value 3000.0, :unit \"metre\"})"]}
7 | {:text ["8 miles"]
8 | :checks [#clj-duckling/corpus "(distance 8 \"mile\" {:value 12872, :unit \"metre\"})"]}
9 | {:text ["9m"]
10 | :checks [#clj-duckling/corpus "(distance 9 \"m\")"]}
11 | {:text ["2cm" "2 centimeters"]
12 | :checks [#clj-duckling/corpus "(distance 2 \"centimetre\" {:value 0.02, :unit \"metre\"})"]}
13 | {:text ["250 milliliters" "250ml" "250 ml"]
14 | :checks [#clj-duckling/corpus "(volume 250 \"millilitre\" {:value 0.25, :unit \"litre\"})"]}
15 | {:text ["2 liters"]
16 | :checks [#clj-duckling/corpus "(volume 2 \"litre\")"]}
17 | {:text ["3 gallons" "3 gal"]
18 | :checks [#clj-duckling/corpus "(volume 3 \"gallon\" {:value 11.355, :unit \"litre\"})"]}
19 | {:text ["3 hectoliters"]
20 | :checks [#clj-duckling/corpus "(volume 300 \"litre\" {:value 30, :unit \"litre\"})"]}
21 | {:text ["half liter"]
22 | :checks [#clj-duckling/corpus "(volume 0.5 \"litre\")"]}
23 | {:text ["two pounds of meat"]
24 | :checks [#clj-duckling/corpus "(quantity 2 \"pound\" \"meat\")"]}
25 | {:text ["a pound"]
26 | :checks [#clj-duckling/corpus "(quantity 1 \"pound\")"]}
27 | {:text ["a meat"]
28 | :checks [#clj-duckling/corpus "(quantity 1 nil \"meat\")"]}
29 | {:text ["3 cups of sugar"]
30 | :checks [#clj-duckling/corpus "(quantity 3 \"cup\" \"sugar\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/et/corpus/_measure.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["3 kilomeetrit" "3 km" "3km" "3k"]
4 | :checks [#clj-duckling/corpus "(distance 3 \"kilometre\" {:value 3000, :unit \"metre\"})"]}
5 | {:text ["3.0 km"]
6 | :checks [#clj-duckling/corpus "(distance 3.0 \"kilometre\" {:value 3000.0, :unit \"metre\"})"]}
7 | {:text ["8 miili"]
8 | :checks [#clj-duckling/corpus "(distance 8 \"mile\" {:value 12872, :unit \"metre\"})"]}
9 | {:text ["9m"]
10 | :checks [#clj-duckling/corpus "(distance 9 \"m\")"]}
11 | {:text ["2cm" "2 sentimeetrit"]
12 | :checks [#clj-duckling/corpus "(distance 2 \"centimetre\" {:value 0.02, :unit \"metre\"})"]}
13 | {:text ["250 milliliitrit" "250ml" "250 ml"]
14 | :checks [#clj-duckling/corpus "(volume 250 \"millilitre\" {:value 0.25, :unit \"litre\"})"]}
15 | {:text ["2 liitrit"]
16 | :checks [#clj-duckling/corpus "(volume 2 \"litre\")"]}
17 | {:text ["3 gallonit" "3 gal"]
18 | :checks [#clj-duckling/corpus "(volume 3 \"gallon\" {:value 11.355, :unit \"litre\"})"]}
19 | {:text ["3 hektoliitrit" "3 kuupliitrit"]
20 | :checks [#clj-duckling/corpus "(volume 300 \"litre\" {:value 30, :unit \"litre\"})"]}
21 | {:text ["pool liitrit"]
22 | :checks [#clj-duckling/corpus "(volume 0.5 \"litre\")"]}
23 | {:text ["kaks naela liha"]
24 | :checks [#clj-duckling/corpus "(quantity 2 \"pound\" \"meat\")"]}
25 | {:text ["nael"]
26 | :checks [#clj-duckling/corpus "(quantity 1 \"pound\")"]}
27 | {:text ["liha"]
28 | :checks [#clj-duckling/corpus "(quantity 1 nil \"meat\")"]}
29 | {:text ["3 klaasi suhkrut"]
30 | :checks [#clj-duckling/corpus "(quantity 3 \"cup\" \"sugar\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/ko/corpus/measure.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["3 킬로미터" "3 킬로" "3 키로" "3 km" "3km"]
4 | :checks [#clj-duckling/corpus "(distance 3 \"kilometre\" {:value 3000, :unit \"metre\"})"]}
5 | {:text ["3.0 km"]
6 | :checks [#clj-duckling/corpus "(distance 3.0 \"kilometre\" {:value 3000.0, :unit \"metre\"})"]}
7 | {:text ["8 miles" "8 마일" "8 마일즈"]
8 | :checks [#clj-duckling/corpus "(distance 8 \"mile\" {:value 12872, :unit \"metre\"})"]}
9 | {:text ["9m" "9미터" "9메터" "구메터"]
10 | :checks [#clj-duckling/corpus "(distance 9 \"metre\")"]}
11 | {:text ["2cm" "2 센치" "이센치" "2 센티" "2 센티미터" "2 센치미터"]
12 | :checks [#clj-duckling/corpus "(distance 2 \"centimetre\" {:value 0.02, :unit \"metre\"})"]}
13 | {:text ["250 밀리리터" "250 미리리터" "이백오십미리리터" "250ml" "250 ml"]
14 | :checks [#clj-duckling/corpus "(volume 250 \"millilitre\" {:value 0.25, :unit \"litre\"})"]}
15 | {:text ["2 리터" "이리터"]
16 | :checks [#clj-duckling/corpus "(volume 2 \"litre\")"]}
17 | {:text ["3 갤론" "삼 갤론"]
18 | :checks [#clj-duckling/corpus "(volume 3 \"gallon\" {:value 11.355, :unit \"litre\"})"]}
19 | {:text ["3 헥토리터" "삼 헥토리터"]
20 | :checks [#clj-duckling/corpus "(volume 300 \"litre\" {:value 30, :unit \"litre\"})"]}
21 | {:text ["반 리터"]
22 | :checks [#clj-duckling/corpus "(volume 0.5 \"litre\")"]}
23 | {:text ["삼겹살 두근"]
24 | :checks [#clj-duckling/corpus "(quantity 2 \"근\" \"삼겹살\")"]}
25 | {:text ["한근"]
26 | :checks [#clj-duckling/corpus "(quantity 1 \"근\")"]}
27 | {:text ["육백그람"]
28 | :checks [#clj-duckling/corpus "(quantity 1 \"그램\")"]}
29 | {:text ["콜라 세컵"]
30 | :checks [#clj-duckling/corpus "(quantity 3 \"컵\" \"콜라\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/zh/corpus/number.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "〇" "零" "零个" "0个"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "一" "一个" "1个"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["10" "十"]
8 | :checks [#clj-duckling/corpus "(number 10)"]}
9 | {:text ["11" "十一"]
10 | :checks [#clj-duckling/corpus "(number 11)"]}
11 | {:text ["20" "二十"]
12 | :checks [#clj-duckling/corpus "(number 20)"]}
13 | {:text ["60" "六十"]
14 | :checks [#clj-duckling/corpus "(number 60)"]}
15 | {:text ["33" "三十三"]
16 | :checks [#clj-duckling/corpus "(number 33)"]}
17 | {:text ["96" "九十六"]
18 | :checks [#clj-duckling/corpus "(number 96)"]}
19 | {:text ["1.1" "1.10" "01.10"]
20 | :checks [#clj-duckling/corpus "(number 1.1)"]}
21 | {:text ["0.77" ".77"]
22 | :checks [#clj-duckling/corpus "(number 0.77)"]}
23 | {:text ["100,000" "100000" "100K" "100k"]
24 | :checks [#clj-duckling/corpus "(number 100000)"]}
25 | {:text ["3M" "3000K" "3000000" "3,000,000"]
26 | :checks [#clj-duckling/corpus "(number 3000000)"]}
27 | {:text ["1,200,000" "1200000" "1.2M" "1200K" ".0012G"]
28 | :checks [#clj-duckling/corpus "(number 1200000)"]}
29 | {:text ["- 1,200,000" "-1200000" "负1,200,000" "负 1,200,000" "負 1,200,000" "负1200000" "负 1200000" "-1.2M" "-1200K" "-.0012G"]
30 | :checks [#clj-duckling/corpus "(number -1200000)"]}
31 | {:text ["第七"]
32 | :checks [#clj-duckling/corpus "(ordinal 7)"]}
33 | {:text ["第十一"]
34 | :checks [#clj-duckling/corpus "(ordinal 11)"]}
35 | {:text ["第九十一"]
36 | :checks [#clj-duckling/corpus "(ordinal 91)"]}]}
--------------------------------------------------------------------------------
/resources/languages/zh/corpus/numbers.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["0" "〇" "零" "零个" "0个"]
4 | :checks [#clj-duckling/corpus "(number 0)"]}
5 | {:text ["1" "一" "一个" "1个"]
6 | :checks [#clj-duckling/corpus "(number 1)"]}
7 | {:text ["10" "十"]
8 | :checks [#clj-duckling/corpus "(number 10)"]}
9 | {:text ["11" "十一"]
10 | :checks [#clj-duckling/corpus "(number 11)"]}
11 | {:text ["20" "二十"]
12 | :checks [#clj-duckling/corpus "(number 20)"]}
13 | {:text ["60" "六十"]
14 | :checks [#clj-duckling/corpus "(number 60)"]}
15 | {:text ["33" "三十三"]
16 | :checks [#clj-duckling/corpus "(number 33)"]}
17 | {:text ["96" "九十六"]
18 | :checks [#clj-duckling/corpus "(number 96)"]}
19 | {:text ["1.1" "1.10" "01.10"]
20 | :checks [#clj-duckling/corpus "(number 1.1)"]}
21 | {:text ["0.77" ".77"]
22 | :checks [#clj-duckling/corpus "(number 0.77)"]}
23 | {:text ["100,000" "100000" "100K" "100k"]
24 | :checks [#clj-duckling/corpus "(number 100000)"]}
25 | {:text ["3M" "3000K" "3000000" "3,000,000"]
26 | :checks [#clj-duckling/corpus "(number 3000000)"]}
27 | {:text ["1,200,000" "1200000" "1.2M" "1200K" ".0012G"]
28 | :checks [#clj-duckling/corpus "(number 1200000)"]}
29 | {:text ["- 1,200,000" "-1200000" "负1,200,000" "负 1,200,000" "負 1,200,000" "负1200000" "负 1200000" "-1.2M" "-1200K" "-.0012G"]
30 | :checks [#clj-duckling/corpus "(number -1200000)"]}
31 | {:text ["第七"]
32 | :checks [#clj-duckling/corpus "(ordinal 7)"]}
33 | {:text ["第十一"]
34 | :checks [#clj-duckling/corpus "(ordinal 11)"]}
35 | {:text ["第九十一"]
36 | :checks [#clj-duckling/corpus "(ordinal 91)"]}]}
--------------------------------------------------------------------------------
/resources/languages/nl/rules/cycle.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "second (cycle)", :pattern "#\"(?i)seconde(n?)?\"", :production "{:dim :cycle, :grain :second}"}
2 | #clj-duckling.engine/rule {:name "minute (cycle)", :pattern "#\"(?i)minuten|minuut?\"", :production "{:dim :cycle, :grain :minute}"}
3 | #clj-duckling.engine/rule {:name "hour (cycle)", :pattern "#\"(?i)uur?\"", :production "{:dim :cycle, :grain :hour}"}
4 | #clj-duckling.engine/rule {:name "day (cycle)", :pattern "#\"(?i)dag(en?)?\"", :production "{:dim :cycle, :grain :day}"}
5 | #clj-duckling.engine/rule {:name "week (cycle)", :pattern "#\"(?i)week|weken?\"", :production "{:dim :cycle, :grain :week}"}
6 | #clj-duckling.engine/rule {:name "month (cycle)", :pattern "#\"(?i)maand(en)?\"", :production "{:dim :cycle, :grain :month}"}
7 | #clj-duckling.engine/rule {:name "quarter (cycle)", :pattern "#\"(?i)kwart?\"", :production "{:dim :cycle, :grain :quarter}"}
8 | #clj-duckling.engine/rule {:name "year (cycle)", :pattern "#\"(?i)jaar?\"", :production "{:dim :cycle, :grain :year}"}
9 | #clj-duckling.engine/rule {:name "this ", :pattern "[#\"(?i)deze|dit\" (dim :cycle)]", :production "(cycle-nth (:grain %2) 0)"}
10 | #clj-duckling.engine/rule {:name "last ", :pattern "[#\"(?i)afgelopen|vorig(e)?\" (dim :cycle)]", :production "(cycle-nth (:grain %2) -1)"}
11 | #clj-duckling.engine/rule {:name "next ", :pattern "[#\"(?i)over|volgend(e)?\" (dim :cycle)]", :production "(cycle-nth (:grain %2) 1)"}
12 | #clj-duckling.engine/rule {:name "next n ", :pattern "[#\"(?i)over\" (integer 1 9999) (dim :cycle)]", :production "(cycle-n-not-immediate (:grain %3) (:value %2))"}
13 | #clj-duckling.engine/rule {:name "last n ", :pattern "[#\"(?i)laatste|afgelopen|voor\" (integer 1 9999) (dim :cycle)]", :production "(cycle-n-not-immediate (:grain %3) (- (:value %2)))"}]
--------------------------------------------------------------------------------
/resources/languages/fr/corpus/measure.edn:
--------------------------------------------------------------------------------
1 | {:context {}
2 |
3 | :tests [{:text ["3 kilomètres" "3 kilometres" "3 km" "3km" "3k"]
4 | :checks [#clj-duckling/corpus "(distance 3 \"kilometre\" {:value 3000, :unit \"metre\"})"]}
5 | {:text ["3,0 km"]
6 | :checks [#clj-duckling/corpus "(distance 3.0 \"kilometre\" {:value 3000.0, :unit \"metre\"})"]}
7 | {:text ["8 miles"]
8 | :checks [#clj-duckling/corpus "(distance 8 \"mile\" {:value 12872, :unit \"metre\"})"]}
9 | {:text ["9 metres" "9m"]
10 | :checks [#clj-duckling/corpus "(distance 9 \"metre\")"]}
11 | {:text ["2cm" "2 centimetres"]
12 | :checks [#clj-duckling/corpus "(distance 2 \"centimetre\" {:value 0.02, :unit \"metre\"})"]}
13 | {:text ["250 millilitres" "250ml" "250 ml"]
14 | :checks [#clj-duckling/corpus "(volume 250 \"millilitre\" {:value 0.25, :unit \"litre\"})"]}
15 | {:text ["2 litres"]
16 | :checks [#clj-duckling/corpus "(volume 2 \"litre\")"]}
17 | {:text ["3 gallons" "3 gal"]
18 | :checks [#clj-duckling/corpus "(volume 3 \"gallon\" {:value 11.355, :unit \"litre\"})"]}
19 | {:text ["3 hectolitres"]
20 | :checks [#clj-duckling/corpus "(volume 300 \"litre\" {:value 30, :unit \"litre\"})"]}
21 | {:text ["demi-litre" "demi litre"]
22 | :checks [#clj-duckling/corpus "(volume 0.5 \"litre\")"]}
23 | {:text ["2 tasses de café"]
24 | :checks [#clj-duckling/corpus "(quantity 2 \"tasse\" \"café\")"]}
25 | {:text ["une tasse"]
26 | :checks [#clj-duckling/corpus "(quantity 1 \"tasse\")"]}
27 | {:text ["un café"]
28 | :checks [#clj-duckling/corpus "(quantity 1 nil \"café\")"]}
29 | {:text ["3 cuillères à soupe de sucre"]
30 | :checks [#clj-duckling/corpus "(quantity 3 \"cuillère à soupe\" \"sucre\")"]}]}
--------------------------------------------------------------------------------
/resources/languages/ja/rules/cycle.edn:
--------------------------------------------------------------------------------
1 | [#clj-duckling.engine/rule {:name "second (cycle)", :pattern "#\"秒毎?\"", :production "{:dim :cycle, :grain :second}"}
2 | #clj-duckling.engine/rule {:name "minute (cycle)", :pattern "#\"分毎?\"", :production "{:dim :cycle, :grain :minute}"}
3 | #clj-duckling.engine/rule {:name "hour (cycle)", :pattern "#\"時毎?\"", :production "{:dim :cycle, :grain :hour}"}
4 | #clj-duckling.engine/rule {:name "day (cycle)", :pattern "#\"日毎?\"", :production "{:dim :cycle, :grain :day}"}
5 | #clj-duckling.engine/rule {:name "week (cycle)", :pattern "#\"週毎?\"", :production "{:dim :cycle, :grain :week}"}
6 | #clj-duckling.engine/rule {:name "month (cycle)", :pattern "#\"月毎?\"", :production "{:dim :cycle, :grain :month}"}
7 | #clj-duckling.engine/rule {:name "year (cycle)", :pattern "#\"年毎?\"", :production "{:dim :cycle, :grain :year}"}
8 | #clj-duckling.engine/rule {:name "this ", :pattern "[#\"毎\" (dim :cycle)]", :production "(cycle-nth (:grain %2) 0)"}
9 | #clj-duckling.engine/rule {:name "last ", :pattern "[#\"上[个|個]?\" (dim :cycle)]", :production "(cycle-nth (:grain %2) -1)"}
10 | #clj-duckling.engine/rule {:name "next ", :pattern "[#\"下[个|個]?\" (dim :cycle)]", :production "(cycle-nth (:grain %2) 1)"}
11 | #clj-duckling.engine/rule {:name "the after