From 8e8f2b655dcd666b40c7f356c4d0d704b030f1a4 Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Mon, 20 Apr 2020 23:37:26 +0000 Subject: [PATCH 01/14] Reorganize deps.edn --- deps.edn | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/deps.edn b/deps.edn index 92063a7..e9f2596 100644 --- a/deps.edn +++ b/deps.edn @@ -1,10 +1,8 @@ -{:aliases - {:test {:extra-deps - #:lambdaisland{kaocha #:mvn{:version "0.0-565"} - kaocha-cljs #:mvn{:version "0.0-68"}} - :extra-paths ["test"] - :main-opts ["-m" "kaocha.runner"]}} - :deps {org.clojure/clojure #:mvn{:version "1.10.1"} - org.clojure/spec.alpha #:mvn{:version "0.2.176"} - org.clojure/test.check #:mvn{:version "0.10.0"}} - :paths ["src"]} +{:paths ["src"] + :deps {org.clojure/clojure {:mvn/version "1.10.1"} + org.clojure/spec.alpha {:mvn/version "0.2.187"} + org.clojure/test.check {:mvn/version "1.0.0"}} + :aliases {:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.0-612"} + lambdaisland/kaocha-cljs {:mvn/version "0.0-71"}} + :extra-paths ["test"] + :main-opts ["-m" "kaocha.runner"]}}} From 68e0d1ec3c09849eaeb9dbea564818b7350f3897 Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Mon, 20 Apr 2020 23:57:24 +0000 Subject: [PATCH 02/14] Adds a test runner watch cmd --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index cc08998..931498b 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,9 @@ all: test test: node_modules clojure -A:test +test-watch: node_modules + clojure -C:test -R:test -m kaocha.runner --watch + lint: clj-kondo --lint src test From 05dc0ad9b14f8ed2eb64e2dbfb6749cbe5cd6ffb Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Mon, 20 Apr 2020 23:57:50 +0000 Subject: [PATCH 03/14] Adds instaparse We'll need this to cope with pint's unit definition syntax. --- deps.edn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deps.edn b/deps.edn index e9f2596..8a13835 100644 --- a/deps.edn +++ b/deps.edn @@ -1,5 +1,6 @@ {:paths ["src"] - :deps {org.clojure/clojure {:mvn/version "1.10.1"} + :deps {instaparse {:mvn/version "1.4.10"} + org.clojure/clojure {:mvn/version "1.10.1"} org.clojure/spec.alpha {:mvn/version "0.2.187"} org.clojure/test.check {:mvn/version "1.0.0"}} :aliases {:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.0-612"} From 590293001c494b2bca09370be954d96b962ff11f Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Mon, 20 Apr 2020 23:58:15 +0000 Subject: [PATCH 04/14] Pulls in pint unit definitions We'll want to be line-for-line compatible to maximize our ability to stand on Pint's shoulders, here. --- resources/default_en.txt | 845 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 845 insertions(+) create mode 100644 resources/default_en.txt diff --git a/resources/default_en.txt b/resources/default_en.txt new file mode 100644 index 0000000..8bd4133 --- /dev/null +++ b/resources/default_en.txt @@ -0,0 +1,845 @@ +# Default Pint units definition file +# Based on the International System of Units +# Language: english +# :copyright: 2013,2019 by Pint Authors, see AUTHORS for more details. + +# Syntax +# ====== +# Units +# ----- +# = [= ] [= ] [ = ] [...] +# +# The canonical name and aliases should be expressed in singular form. +# Pint automatically deals with plurals built by adding 's' to the singular form; plural +# forms that don't follow this rule should be instead explicitly listed as aliases. +# +# If a unit has no symbol and one wants to define aliases, then the symbol should be +# conventionally set to _. +# +# Example: +# millennium = 1e3 * year = _ = millennia +# +# +# Prefixes +# -------- +# - = [= ] [= ] [ = ] [...] +# +# Example: +# deca- = 1e+1 = da- = deka- +# +# +# Derived dimensions +# ------------------ +# [dimension name] = +# +# Example: +# [density] = [mass] / [volume] +# +# Note that primary dimensions don't need to be declared; they can be +# defined for the first time in a unit definition. +# E.g. see below `meter = [length]` +# +# +# Additional aliases +# ------------------ +# @alias = [ = ] [...] +# +# Used to add aliases to already existing unit definitions. +# Particularly useful when one wants to enrich definitions +# from defaults_en.txt with custom aliases. +# +# Example: +# @alias meter = my_meter + +# See also: https://pint.readthedocs.io/en/latest/defining.html + +@defaults + group = international + system = mks +@end + + +#### PREFIXES #### + +# decimal prefixes +yocto- = 1e-24 = y- +zepto- = 1e-21 = z- +atto- = 1e-18 = a- +femto- = 1e-15 = f- +pico- = 1e-12 = p- +nano- = 1e-9 = n- +micro- = 1e-6 = µ- = u- +milli- = 1e-3 = m- +centi- = 1e-2 = c- +deci- = 1e-1 = d- +deca- = 1e+1 = da- = deka- +hecto- = 1e2 = h- +kilo- = 1e3 = k- +mega- = 1e6 = M- +giga- = 1e9 = G- +tera- = 1e12 = T- +peta- = 1e15 = P- +exa- = 1e18 = E- +zetta- = 1e21 = Z- +yotta- = 1e24 = Y- + +# binary_prefixes +kibi- = 2**10 = Ki- +mebi- = 2**20 = Mi- +gibi- = 2**30 = Gi- +tebi- = 2**40 = Ti- +pebi- = 2**50 = Pi- +exbi- = 2**60 = Ei- +zebi- = 2**70 = Zi- +yobi- = 2**80 = Yi- + +# extra_prefixes +semi- = 0.5 = _ = demi- +sesqui- = 1.5 + + +#### BASE UNITS #### + +meter = [length] = m = metre +second = [time] = s = sec +ampere = [current] = A = amp +candela = [luminosity] = cd = candle +gram = [mass] = g +mole = [substance] = mol +kelvin = [temperature]; offset: 0 = K = degK = °K = degree_Kelvin = degreeK # older names supported for compatibility +radian = [] = rad +neper = [] = Np +bit = [] +count = [] + + +#### CONSTANTS #### + +@import constants_en.txt + + +#### UNITS #### +# Common and less common, grouped by quantity. +# Conversion factors are exact (except when noted), +# although floating-point conversion may introduce inaccuracies + +# Angle +turn = 2 * π * radian = _ = revolution = cycle = circle +degree = π / 180 * radian = deg = arcdeg = arcdegree = angular_degree +arcminute = degree / 60 = arcmin = arc_minute = angular_minute +arcsecond = arcminute / 60 = arcsec = arc_second = angular_second +milliarcsecond = 1e-3 * arcsecond = mas +grade = π / 200 * radian = grad = gon +mil = π / 32000 * radian + +# Solid angle +steradian = radian ** 2 = sr +square_degree = (π / 180) ** 2 * sr = sq_deg = sqdeg + +# Logarithmic ratio +bel = 0.5 * ln10 * neper + +# Information +byte = 8 * bit = B = octet +baud = bit / second = Bd = bps + +# Length +angstrom = 1e-10 * meter = Å = ångström = Å +micron = micrometer = µ +fermi = femtometer = fm +light_year = speed_of_light * julian_year = ly = lightyear +astronomical_unit = 149597870700 * meter = au # since Aug 2012 +parsec = 1 / tansec * astronomical_unit = pc +nautical_mile = 1852 * meter = nmi +bohr = hbar / (alpha * m_e * c) = a_0 = a0 = bohr_radius = atomic_unit_of_length = a_u_length +x_unit_Cu = K_alpha_Cu_d_220 * d_220 / 1537.4 = Xu_Cu +x_unit_Mo = K_alpha_Mo_d_220 * d_220 / 707.831 = Xu_Mo +angstrom_star = K_alpha_W_d_220 * d_220 / 0.2090100 = Å_star +planck_length = (hbar * gravitational_constant / c ** 3) ** 0.5 + +# Mass +metric_ton = 1e3 * kilogram = t = tonne +unified_atomic_mass_unit = atomic_mass_constant = u = amu +dalton = atomic_mass_constant = Da +grain = 64.79891 * milligram = gr +gamma_mass = microgram +carat = 200 * milligram = ct = karat +planck_mass = (hbar * c / gravitational_constant) ** 0.5 + +# Time +minute = 60 * second = min +hour = 60 * minute = hr +day = 24 * hour = d +week = 7 * day +fortnight = 2 * week +year = 365.25 * day = a = yr = julian_year +month = year / 12 +decade = 10 * year +century = 100 * year = _ = centuries +millennium = 1e3 * year = _ = millennia +eon = 1e9 * year +shake = 1e-8 * second +svedberg = 1e-13 * second +atomic_unit_of_time = hbar / E_h = a_u_time +gregorian_year = 365.2425 * day +sidereal_year = 365.256363004 * day # approximate, as of J2000 epoch +tropical_year = 365.242190402 * day # approximate, as of J2000 epoch +common_year = 365 * day +leap_year = 366 * day +sidereal_day = day / 1.00273790935079524 # approximate +sidereal_month = 27.32166155 * day # approximate +tropical_month = 27.321582 * day # approximate +synodic_month = 29.530589 * day = _ = lunar_month # approximate +planck_time = (hbar * gravitational_constant / c ** 5) ** 0.5 + +# Temperature +degree_Celsius = kelvin; offset: 273.15 = °C = celsius = degC = degreeC +degree_Rankine = 5 / 9 * kelvin; offset: 0 = °R = rankine = degR = degreeR +degree_Fahrenheit = 5 / 9 * kelvin; offset: 233.15 + 200 / 9 = °F = fahrenheit = degF = degreeF +degree_Reaumur = 4 / 5 * kelvin; offset: 273.15 = °Re = reaumur = degRe = degreeRe = degree_Réaumur = réaumur +atomic_unit_of_temperature = E_h / k = a_u_temp +planck_temperature = (hbar * c ** 5 / gravitational_constant / k ** 2) ** 0.5 + +# Area +[area] = [length] ** 2 +are = 100 * meter ** 2 +barn = 1e-28 * meter ** 2 = b +darcy = centipoise * centimeter ** 2 / (second * atmosphere) +hectare = 100 * are = ha + +# Volume +[volume] = [length] ** 3 +liter = decimeter ** 3 = l = L = litre +cubic_centimeter = centimeter ** 3 = cc +lambda = microliter = λ +stere = meter ** 3 + +# Frequency +[frequency] = 1 / [time] +hertz = 1 / second = Hz +revolutions_per_minute = revolution / minute = rpm +revolutions_per_second = revolution / second = rps +counts_per_second = count / second = cps + +# Wavenumber +[wavenumber] = 1 / [length] +reciprocal_centimeter = 1 / cm = cm_1 = kayser + +# Velocity +[velocity] = [length] / [time] = [speed] +knot = nautical_mile / hour = kt = knot_international = international_knot +mile_per_hour = mile / hour = mph = MPH +kilometer_per_hour = kilometer / hour = kph = KPH +kilometer_per_second = kilometer / second = kps +meter_per_second = meter / second = mps +foot_per_second = foot / second = fps + +# Acceleration +[acceleration] = [velocity] / [time] +galileo = centimeter / second ** 2 = Gal + +# Force +[force] = [mass] * [acceleration] +newton = kilogram * meter / second ** 2 = N +dyne = gram * centimeter / second ** 2 = dyn +force_kilogram = g_0 * kilogram = kgf = kilogram_force = pond +force_gram = g_0 * gram = gf = gram_force +force_metric_ton = g_0 * metric_ton = tf = metric_ton_force = force_t = t_force +atomic_unit_of_force = E_h / a_0 = a_u_force + +# Energy +[energy] = [force] * [length] +joule = newton * meter = J +erg = dyne * centimeter +watt_hour = watt * hour = Wh = watthour +electron_volt = e * volt = eV +rydberg = h * c * R_inf = Ry +hartree = 2 * rydberg = E_h = Eh = hartree_energy = atomic_unit_of_energy = a_u_energy +calorie = 4.184 * joule = cal = thermochemical_calorie = cal_th +international_calorie = 4.1868 * joule = cal_it = international_steam_table_calorie +fifteen_degree_calorie = 4.1855 * joule = cal_15 +british_thermal_unit = 1055.056 * joule = Btu = BTU = Btu_iso +international_british_thermal_unit = 1e3 * pound / kilogram * degR / kelvin * international_calorie = Btu_it +thermochemical_british_thermal_unit = 1e3 * pound / kilogram * degR / kelvin * calorie = Btu_th +quadrillion_Btu = 1e15 * Btu = quad +therm = 1e5 * Btu = thm = EC_therm +US_therm = 1.054804e8 * joule # approximate, no exact definition +ton_TNT = 1e9 * calorie = tTNT +tonne_of_oil_equivalent = 1e10 * international_calorie = toe +atmosphere_liter = atmosphere * liter = atm_l + +# Power +[power] = [energy] / [time] +watt = joule / second = W +volt_ampere = volt * ampere = VA +horsepower = 550 * foot * force_pound / second = hp = UK_horsepower = hydraulic_horsepower +boiler_horsepower = 33475 * Btu / hour # unclear which Btu +metric_horsepower = 75 * force_kilogram * meter / second +electrical_horsepower = 746 * watt +refrigeration_ton = 12e3 * Btu / hour = _ = ton_of_refrigeration # approximate, no exact definition +standard_liter_per_minute = atmosphere * liter / minute = slpm = slm +conventional_watt_90 = K_J90 ** 2 * R_K90 / (K_J ** 2 * R_K) * watt = W_90 + +# Density (as auxiliary for pressure) +[density] = [mass] / [volume] +mercury = 13.5951 * kilogram / liter = Hg = Hg_0C = Hg_32F = conventional_mercury +water = 1.0 * kilogram / liter = H2O = conventional_water +mercury_60F = 13.5568 * kilogram / liter = Hg_60F # approximate +water_39F = 0.999972 * kilogram / liter = water_4C # approximate +water_60F = 0.999001 * kilogram / liter # approximate + +# Pressure +[pressure] = [force] / [area] +pascal = newton / meter ** 2 = Pa +barye = dyne / centimeter ** 2 = Ba = barie = barad = barrie = baryd +bar = 1e5 * pascal +technical_atmosphere = kilogram * g_0 / centimeter ** 2 = at +torr = atm / 760 +pound_force_per_square_inch = force_pound / inch ** 2 = psi +kip_per_square_inch = kip / inch ** 2 = ksi +millimeter_Hg = millimeter * Hg * g_0 = mmHg = mm_Hg = millimeter_Hg_0C +centimeter_Hg = centimeter * Hg * g_0 = cmHg = cm_Hg = centimeter_Hg_0C +inch_Hg = inch * Hg * g_0 = inHg = in_Hg = inch_Hg_32F +inch_Hg_60F = inch * Hg_60F * g_0 +inch_H2O_39F = inch * water_39F * g_0 +inch_H2O_60F = inch * water_60F * g_0 +foot_H2O = foot * water * g_0 = ftH2O = feet_H2O +centimeter_H2O = centimeter * water * g_0 = cmH2O = cm_H2O + +# Torque +[torque] = [force] * [length] +foot_pound = foot * force_pound = ft_lb = footpound + +# Viscosity +[viscosity] = [pressure] * [time] +poise = 0.1 * Pa * second = P +reyn = psi * second + +# Kinematic viscosity +[kinematic_viscosity] = [area] / [time] +stokes = centimeter ** 2 / second = St + +# Fluidity +[fluidity] = 1 / [viscosity] +rhe = 1 / poise + +# Amount of substance +particle = 1 / N_A = _ = molec = molecule + +# Concentration +[concentration] = [substance] / [volume] +molar = mole / liter = M + +# Catalytic activity +[activity] = [substance] / [time] +katal = mole / second = kat +enzyme_unit = micromole / minute = U = enzymeunit + +# Entropy +[entropy] = [energy] / [temperature] +clausius = calorie / kelvin = Cl + +# Molar entropy +[molar_entropy] = [entropy] / [substance] +entropy_unit = calorie / kelvin / mole = eu + +# Radiation +becquerel = counts_per_second = Bq +curie = 3.7e10 * becquerel = Ci +rutherford = 1e6 * becquerel = Rd +gray = joule / kilogram = Gy +sievert = joule / kilogram = Sv +rads = 0.01 * gray +rem = 0.01 * sievert +roentgen = 2.58e-4 * coulomb / kilogram = _ = röntgen # approximate, depends on medium + +# Heat transimission +[heat_transmission] = [energy] / [area] +peak_sun_hour = 1e3 * watt_hour / meter ** 2 = PSH +langley = thermochemical_calorie / centimeter ** 2 = Ly + +# Luminance +[luminance] = [luminosity] / [area] +nit = candela / meter ** 2 +stilb = candela / centimeter ** 2 +lambert = 1 / π * candela / centimeter ** 2 + +# Luminous flux +[luminous_flux] = [luminosity] +lumen = candela * steradian = lm + +# Illuminance +[illuminance] = [luminous_flux] / [area] +lux = lumen / meter ** 2 = lx + +# Intensity +[intensity] = [power] / [area] +atomic_unit_of_intensity = 0.5 * ε_0 * c * atomic_unit_of_electric_field ** 2 = a_u_intensity + +# Current +biot = 10 * ampere = Bi +abampere = biot = abA +atomic_unit_of_current = e / atomic_unit_of_time = a_u_current +mean_international_ampere = mean_international_volt / mean_international_ohm = A_it +US_international_ampere = US_international_volt / US_international_ohm = A_US +conventional_ampere_90 = K_J90 * R_K90 / (K_J * R_K) * ampere = A_90 +planck_current = (c ** 6 / gravitational_constant / k_C) ** 0.5 + +# Charge +[charge] = [current] * [time] +coulomb = ampere * second = C +abcoulomb = 10 * C = abC +faraday = e * N_A * mole +conventional_coulomb_90 = K_J90 * R_K90 / (K_J * R_K) * coulomb = C_90 + +# Electric potential +[electric_potential] = [energy] / [charge] +volt = joule / coulomb = V +abvolt = 1e-8 * volt = abV +mean_international_volt = 1.00034 * volt = V_it # approximate +US_international_volt = 1.00033 * volt = V_US # approximate +conventional_volt_90 = K_J90 / K_J * volt = V_90 + +# Electric field +[electric_field] = [electric_potential] / [length] +atomic_unit_of_electric_field = e * k_C / a_0 ** 2 = a_u_electric_field + +# Electric displacement field +[electric_displacement_field] = [charge] / [area] + +# Resistance +[resistance] = [electric_potential] / [current] +ohm = volt / ampere = Ω +abohm = 1e-9 * ohm = abΩ +mean_international_ohm = 1.00049 * ohm = Ω_it = ohm_it # approximate +US_international_ohm = 1.000495 * ohm = Ω_US = ohm_US # approximate +conventional_ohm_90 = R_K / R_K90 * ohm = Ω_90 = ohm_90 + +# Resistivity +[resistivity] = [resistance] * [length] + +# Conductance +[conductance] = [current] / [electric_potential] +siemens = ampere / volt = S = mho +absiemens = 1e9 * siemens = abS = abmho + +# Capacitance +[capacitance] = [charge] / [electric_potential] +farad = coulomb / volt = F +abfarad = 1e9 * farad = abF +conventional_farad_90 = R_K90 / R_K * farad = F_90 + +# Inductance +[inductance] = [magnetic_flux] / [current] +henry = weber / ampere = H +abhenry = 1e-9 * henry = abH +conventional_henry_90 = R_K / R_K90 * henry = H_90 + +# Magnetic flux +[magnetic_flux] = [electric_potential] * [time] +weber = volt * second = Wb +unit_pole = µ_0 * biot * centimeter + +# Magnetic field +[magnetic_field] = [magnetic_flux] / [area] +tesla = weber / meter ** 2 = T +gamma = 1e-9 * tesla = γ + +# Magnetomotive force +[magnetomotive_force] = [current] +ampere_turn = ampere = At +biot_turn = biot +gilbert = 1 / (4 * π) * biot_turn = Gb + +# Magnetic field strength +[magnetic_field_strength] = [current] / [length] + +# Electric dipole moment +[electric_dipole] = [charge] * [length] +debye = 1e-9 / ζ * coulomb * angstrom = D # formally 1 D = 1e-10 Fr*Å, but we generally want to use it outside the Gaussian context + +# Electric quadrupole moment +[electric_quadrupole] = [charge] * [area] +buckingham = debye * angstrom + +# Magnetic dipole moment +[magnetic_dipole] = [current] * [area] +bohr_magneton = e * hbar / (2 * m_e) = µ_B = mu_B +nuclear_magneton = e * hbar / (2 * m_p) = µ_N = mu_N + + +#### UNIT GROUPS #### +# Mostly for length, area, volume, mass, force +# (customary or specialized units) + +@group USCSLengthInternational + thou = 1e-3 * inch = th = mil_length + inch = yard / 36 = in = international_inch = inches = international_inches + hand = 4 * inch + foot = yard / 3 = ft = international_foot = feet = international_feet + yard = 0.9144 * meter = yd = international_yard # since Jul 1959 + mile = 1760 * yard = mi = international_mile + + circular_mil = π / 4 * mil_length ** 2 = cmil + square_inch = inch ** 2 = sq_in = square_inches + square_foot = foot ** 2 = sq_ft = square_feet + square_yard = yard ** 2 = sq_yd + square_mile = mile ** 2 = sq_mi + + cubic_inch = in ** 3 = cu_in + cubic_foot = ft ** 3 = cu_ft = cubic_feet + cubic_yard = yd ** 3 = cu_yd +@end + +@group USCSLengthSurvey + link = 1e-2 * chain = li = survey_link + survey_foot = 1200 / 3937 * meter = sft + fathom = 6 * survey_foot + rod = 16.5 * survey_foot = rd = pole = perch + chain = 4 * rod + furlong = 40 * rod = fur + cables_length = 120 * fathom + survey_mile = 5280 * survey_foot = smi = us_statute_mile + league = 3 * survey_mile + + square_rod = rod ** 2 = sq_rod = sq_pole = sq_perch + acre = 10 * chain ** 2 + square_survey_mile = survey_mile ** 2 = _ = section + square_league = league ** 2 + + acre_foot = acre * survey_foot = _ = acre_feet +@end + +@group USCSDryVolume + dry_pint = bushel / 64 = dpi = US_dry_pint + dry_quart = bushel / 32 = dqt = US_dry_quart + dry_gallon = bushel / 8 = dgal = US_dry_gallon + peck = bushel / 4 = pk + bushel = 2150.42 cubic_inch = bu + dry_barrel = 7056 cubic_inch = _ = US_dry_barrel + board_foot = ft * ft * in = FBM = board_feet = BF = BDFT = super_foot = superficial_foot = super_feet = superficial_feet +@end + +@group USCSLiquidVolume + minim = pint / 7680 + fluid_dram = pint / 128 = fldr = fluidram = US_fluid_dram = US_liquid_dram + fluid_ounce = pint / 16 = floz = US_fluid_ounce = US_liquid_ounce + gill = pint / 4 = gi = liquid_gill = US_liquid_gill + pint = quart / 2 = pt = liquid_pint = US_pint + fifth = gallon / 5 = _ = US_liquid_fifth + quart = gallon / 4 = qt = liquid_quart = US_liquid_quart + gallon = 231 * cubic_inch = gal = liquid_gallon = US_liquid_gallon +@end + +@group USCSVolumeOther + teaspoon = fluid_ounce / 6 = tsp + tablespoon = fluid_ounce / 2 = tbsp + shot = 3 * tablespoon = jig = US_shot + cup = pint / 2 = cp = liquid_cup = US_liquid_cup + barrel = 31.5 * gallon = bbl + oil_barrel = 42 * gallon = oil_bbl + beer_barrel = 31 * gallon = beer_bbl + hogshead = 63 * gallon +@end + +@group Avoirdupois + dram = pound / 256 = dr = avoirdupois_dram = avdp_dram = drachm + ounce = pound / 16 = oz = avoirdupois_ounce = avdp_ounce + pound = 7e3 * grain = lb = avoirdupois_pound = avdp_pound + stone = 14 * pound + quarter = 28 * stone + bag = 94 * pound + hundredweight = 100 * pound = cwt = short_hundredweight + long_hundredweight = 112 * pound + ton = 2e3 * pound = _ = short_ton + long_ton = 2240 * pound + slug = g_0 * pound * second ** 2 / foot + slinch = g_0 * pound * second ** 2 / inch = blob = slugette + + force_ounce = g_0 * ounce = ozf = ounce_force + force_pound = g_0 * pound = lbf = pound_force + force_ton = g_0 * ton = _ = ton_force = force_short_ton = short_ton_force + force_long_ton = g_0 * long_ton = _ = long_ton_force + kip = 1e3 * force_pound + poundal = pound * foot / second ** 2 = pdl +@end + +@group AvoirdupoisUK using Avoirdupois + UK_hundredweight = long_hundredweight = UK_cwt + UK_ton = long_ton + UK_force_ton = force_long_ton = _ = UK_ton_force +@end + +@group AvoirdupoisUS using Avoirdupois + US_hundredweight = hundredweight = US_cwt + US_ton = ton + US_force_ton = force_ton = _ = US_ton_force +@end + +@group Troy + pennyweight = 24 * grain = dwt + troy_ounce = 480 * grain = toz = ozt + troy_pound = 12 * troy_ounce = tlb = lbt +@end + +@group Apothecary + scruple = 20 * grain + apothecary_dram = 3 * scruple = ap_dr + apothecary_ounce = 8 * apothecary_dram = ap_oz + apothecary_pound = 12 * apothecary_ounce = ap_lb +@end + +@group ImperialVolume + imperial_minim = imperial_fluid_ounce / 480 + imperial_fluid_scruple = imperial_fluid_ounce / 24 + imperial_fluid_drachm = imperial_fluid_ounce / 8 = imperial_fldr = imperial_fluid_dram + imperial_fluid_ounce = imperial_pint / 20 = imperial_floz = UK_fluid_ounce + imperial_gill = imperial_pint / 4 = imperial_gi = UK_gill + imperial_cup = imperial_pint / 2 = imperial_cp = UK_cup + imperial_pint = imperial_gallon / 8 = imperial_pt = UK_pint + imperial_quart = imperial_gallon / 4 = imperial_qt = UK_quart + imperial_gallon = 4.54609 * liter = imperial_gal = UK_gallon + imperial_peck = 2 * imperial_gallon = imperial_pk = UK_pk + imperial_bushel = 8 * imperial_gallon = imperial_bu = UK_bushel + imperial_barrel = 36 * imperial_gallon = imperial_bbl = UK_bbl +@end + +@group Printer + pica = inch / 6 = _ = printers_pica + point = pica / 12 = pp = printers_point = big_point = bp + didot = 1 / 2660 * m + cicero = 12 * didot + tex_point = inch / 72.27 + tex_pica = 12 * tex_point + tex_didot = 1238 / 1157 * tex_point + tex_cicero = 12 * tex_didot + scaled_point = tex_point / 65536 + css_pixel = inch / 96 = px + + pixel = [printing_unit] = _ = dot = pel = picture_element + pixels_per_centimeter = pixel / cm = PPCM + pixels_per_inch = pixel / inch = dots_per_inch = PPI = ppi = DPI = printers_dpi + bits_per_pixel = bit / pixel = bpp +@end + +@group Textile + tex = gram / kilometer = Tt + dtex = decitex + denier = gram / (9 * kilometer) = den = Td + jute = pound / (14400 * yard) = Tj + aberdeen = jute = Ta + RKM = gf / tex + + number_english = 840 * yard / pound = Ne = NeC = ECC + number_meter = kilometer / kilogram = Nm +@end + + +#### CGS ELECTROMAGNETIC UNITS #### + +# === Gaussian system of units === +@group Gaussian + franklin = erg ** 0.5 * centimeter ** 0.5 = Fr = statcoulomb = statC = esu + statvolt = erg / franklin = statV + statampere = franklin / second = statA + gauss = dyne / franklin = G + maxwell = gauss * centimeter ** 2 = Mx + oersted = dyne / maxwell = Oe = ørsted + statohm = statvolt / statampere = statΩ + statfarad = franklin / statvolt = statF + statmho = statampere / statvolt +@end +# Note this system is not commensurate with SI, as ε_0 and µ_0 disappear; +# some quantities with different dimensions in SI have the same +# dimensions in the Gaussian system (e.g. [Mx] = [Fr], but [Wb] != [C]), +# and therefore the conversion factors depend on the context (not in pint sense) +[gaussian_charge] = [length] ** 1.5 * [mass] ** 0.5 / [time] +[gaussian_current] = [gaussian_charge] / [time] +[gaussian_electric_potential] = [gaussian_charge] / [length] +[gaussian_electric_field] = [gaussian_electric_potential] / [length] +[gaussian_electric_displacement_field] = [gaussian_charge] / [area] +[gaussian_electric_flux] = [gaussian_charge] +[gaussian_electric_dipole] = [gaussian_charge] * [length] +[gaussian_electric_quadrupole] = [gaussian_charge] * [area] +[gaussian_magnetic_field] = [force] / [gaussian_charge] +[gaussian_magnetic_field_strength] = [gaussian_magnetic_field] +[gaussian_magnetic_flux] = [gaussian_magnetic_field] * [area] +[gaussian_magnetic_dipole] = [energy] / [gaussian_magnetic_field] +[gaussian_resistance] = [gaussian_electric_potential] / [gaussian_current] +[gaussian_resistivity] = [gaussian_resistance] * [length] +[gaussian_capacitance] = [gaussian_charge] / [gaussian_electric_potential] +[gaussian_inductance] = [gaussian_electric_potential] * [time] / [gaussian_current] +[gaussian_conductance] = [gaussian_current] / [gaussian_electric_potential] +@context Gaussian = Gau + [gaussian_charge] -> [charge]: value / k_C ** 0.5 + [charge] -> [gaussian_charge]: value * k_C ** 0.5 + [gaussian_current] -> [current]: value / k_C ** 0.5 + [current] -> [gaussian_current]: value * k_C ** 0.5 + [gaussian_electric_potential] -> [electric_potential]: value * k_C ** 0.5 + [electric_potential] -> [gaussian_electric_potential]: value / k_C ** 0.5 + [gaussian_electric_field] -> [electric_field]: value * k_C ** 0.5 + [electric_field] -> [gaussian_electric_field]: value / k_C ** 0.5 + [gaussian_electric_displacement_field] -> [electric_displacement_field]: value / (4 * π / ε_0) ** 0.5 + [electric_displacement_field] -> [gaussian_electric_displacement_field]: value * (4 * π / ε_0) ** 0.5 + [gaussian_electric_dipole] -> [electric_dipole]: value / k_C ** 0.5 + [electric_dipole] -> [gaussian_electric_dipole]: value * k_C ** 0.5 + [gaussian_electric_quadrupole] -> [electric_quadrupole]: value / k_C ** 0.5 + [electric_quadrupole] -> [gaussian_electric_quadrupole]: value * k_C ** 0.5 + [gaussian_magnetic_field] -> [magnetic_field]: value / (4 * π / µ_0) ** 0.5 + [magnetic_field] -> [gaussian_magnetic_field]: value * (4 * π / µ_0) ** 0.5 + [gaussian_magnetic_flux] -> [magnetic_flux]: value / (4 * π / µ_0) ** 0.5 + [magnetic_flux] -> [gaussian_magnetic_flux]: value * (4 * π / µ_0) ** 0.5 + [gaussian_magnetic_field_strength] -> [magnetic_field_strength]: value / (4 * π * µ_0) ** 0.5 + [magnetic_field_strength] -> [gaussian_magnetic_field_strength]: value * (4 * π * µ_0) ** 0.5 + [gaussian_magnetic_dipole] -> [magnetic_dipole]: value * (4 * π / µ_0) ** 0.5 + [magnetic_dipole] -> [gaussian_magnetic_dipole]: value / (4 * π / µ_0) ** 0.5 + [gaussian_resistance] -> [resistance]: value * k_C + [resistance] -> [gaussian_resistance]: value / k_C + [gaussian_resistivity] -> [resistivity]: value * k_C + [resistivity] -> [gaussian_resistivity]: value / k_C + [gaussian_capacitance] -> [capacitance]: value / k_C + [capacitance] -> [gaussian_capacitance]: value * k_C + [gaussian_inductance] -> [inductance]: value * k_C + [inductance] -> [gaussian_inductance]: value / k_C + [gaussian_conductance] -> [conductance]: value / k_C + [conductance] -> [gaussian_conductance]: value * k_C +@end + +# === ESU system of units === +# (where different from Gaussian) +# See note for Gaussian system too +@group ESU using Gaussian + statweber = statvolt * second = statWb + stattesla = statweber / centimeter ** 2 = statT + stathenry = statweber / statampere = statH +@end +[esu_charge] = [length] ** 1.5 * [mass] ** 0.5 / [time] +[esu_current] = [esu_charge] / [time] +[esu_electric_potential] = [esu_charge] / [length] +[esu_magnetic_flux] = [esu_electric_potential] * [time] +[esu_magnetic_field] = [esu_magnetic_flux] / [area] +[esu_magnetic_field_strength] = [esu_current] / [length] +[esu_magnetic_dipole] = [esu_current] * [area] +@context ESU = esu + [esu_magnetic_field] -> [magnetic_field]: value * k_C ** 0.5 + [magnetic_field] -> [esu_magnetic_field]: value / k_C ** 0.5 + [esu_magnetic_flux] -> [magnetic_flux]: value * k_C ** 0.5 + [magnetic_flux] -> [esu_magnetic_flux]: value / k_C ** 0.5 + [esu_magnetic_field_strength] -> [magnetic_field_strength]: value / (4 * π / ε_0) ** 0.5 + [magnetic_field_strength] -> [esu_magnetic_field_strength]: value * (4 * π / ε_0) ** 0.5 + [esu_magnetic_dipole] -> [magnetic_dipole]: value / k_C ** 0.5 + [magnetic_dipole] -> [esu_magnetic_dipole]: value * k_C ** 0.5 +@end + + +#### CONVERSION CONTEXTS #### + +@context(n=1) spectroscopy = sp + # n index of refraction of the medium. + [length] <-> [frequency]: speed_of_light / n / value + [frequency] -> [energy]: planck_constant * value + [energy] -> [frequency]: value / planck_constant + # allow wavenumber / kayser + [wavenumber] <-> [length]: 1 / value +@end + +@context boltzmann + [temperature] -> [energy]: boltzmann_constant * value + [energy] -> [temperature]: value / boltzmann_constant +@end + +@context energy + [energy] -> [energy] / [substance]: value * N_A + [energy] / [substance] -> [energy]: value / N_A + [energy] -> [mass]: value / c ** 2 + [mass] -> [energy]: value * c ** 2 +@end + +@context(mw=0,volume=0,solvent_mass=0) chemistry = chem + # mw is the molecular weight of the species + # volume is the volume of the solution + # solvent_mass is the mass of solvent in the solution + + # moles -> mass require the molecular weight + [substance] -> [mass]: value * mw + [mass] -> [substance]: value / mw + + # moles/volume -> mass/volume and moles/mass -> mass/mass + # require the molecular weight + [substance] / [volume] -> [mass] / [volume]: value * mw + [mass] / [volume] -> [substance] / [volume]: value / mw + [substance] / [mass] -> [mass] / [mass]: value * mw + [mass] / [mass] -> [substance] / [mass]: value / mw + + # moles/volume -> moles requires the solution volume + [substance] / [volume] -> [substance]: value * volume + [substance] -> [substance] / [volume]: value / volume + + # moles/mass -> moles requires the solvent (usually water) mass + [substance] / [mass] -> [substance]: value * solvent_mass + [substance] -> [substance] / [mass]: value / solvent_mass + + # moles/mass -> moles/volume require the solvent mass and the volume + [substance] / [mass] -> [substance]/[volume]: value * solvent_mass / volume + [substance] / [volume] -> [substance] / [mass]: value / solvent_mass * volume + +@end + +@context textile + # Allow switching between Direct count system (i.e. tex) and + # Indirect count system (i.e. Ne, Nm) + [mass] / [length] <-> [length] / [mass]: 1 / value +@end + + +#### SYSTEMS OF UNITS #### + +@system SI + second + meter + kilogram + ampere + kelvin + mole + candela +@end + +@system mks using international + meter + kilogram + second +@end + +@system cgs using international, Gaussian, ESU + centimeter + gram + second +@end + +@system atomic using international + # based on unit m_e, e, hbar, k_C, k + bohr: meter + electron_mass: gram + atomic_unit_of_time: second + atomic_unit_of_current: ampere + atomic_unit_of_temperature: kelvin +@end + +@system Planck using international + # based on unit c, gravitational_constant, hbar, k_C, k + planck_length: meter + planck_mass: gram + planck_time: second + planck_current: ampere + planck_temperature: kelvin +@end + +@system imperial using ImperialVolume, USCSLengthInternational, AvoirdupoisUK + yard + pound +@end + +@system US using USCSLiquidVolume, USCSDryVolume, USCSVolumeOther, USCSLengthInternational, USCSLengthSurvey, AvoirdupoisUS + yard + pound +@end From 6465d80e4a71b30aef7b906ab815b21fb654f9a1 Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Tue, 21 Apr 2020 00:20:40 +0000 Subject: [PATCH 05/14] Stub in interface Make a naive implementation that is just enough to test the construction of record-type quantities with a partial in a separate project. Currently this has zero protection against unregistered units, or implementation of arithmetic or conversion. Going down a record-based implementation to experiment with getting the faster dispatch (that ought to be possible) over the older vector-based tuple implementation. --- src/opengb/dram/core.cljc | 45 +++++++++++++++++++++++++++++ test/opengb/dram/registry_test.cljc | 22 ++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/opengb/dram/core.cljc create mode 100644 test/opengb/dram/registry_test.cljc diff --git a/src/opengb/dram/core.cljc b/src/opengb/dram/core.cljc new file mode 100644 index 0000000..fb50554 --- /dev/null +++ b/src/opengb/dram/core.cljc @@ -0,0 +1,45 @@ +(ns opengb.dram.core + "" + (:require + [clojure.spec.alpha :as s])) + +;; * unit registries + +(defn make-unit-registry + "Make a default unit registry. + + The unit reg is what defines conversions and valid units." + [] + {}) ;; stubbed to test interface + +(defn define-unit + [ureg _unit-definition] + ureg ;; stubbed to test interface + #_(str ureg "\n" _unit-definition)) + +(defn valid-unit? + [_ureg _unit] + true ;; stubbed to test interface + #_(true? (get unit ureg))) + +;; * quantities + +(defprotocol IQuantity + (get-magnitude [q]) + (get-unit [q])) + +(deftype quantity + [^:double mag unit] + IQuantity + (get-magnitude [q] (.-mag q)) + (get-unit [q] (.-unit q))) + +(defn quantity? + [?q] + (= (type ?q) quantity)) + +(defn make-quantity + [unit-registry ^:double mag unit] + {:pre [(s/valid? ::magnitude mag) + (valid-unit? unit-registry unit)]} + (->quantity (double mag) unit)) diff --git a/test/opengb/dram/registry_test.cljc b/test/opengb/dram/registry_test.cljc new file mode 100644 index 0000000..102c2f0 --- /dev/null +++ b/test/opengb/dram/registry_test.cljc @@ -0,0 +1,22 @@ +(ns opengb.dram.registry-test + (:require + [clojure.test :as t :refer [deftest is]] + [opengb.dram.core :as sut])) + +(deftest make-unit-registry + (is (= {} (sut/make-unit-registry)))) + +(def time-definitions + "See https://pint.readthedocs.io/en/0.10.1/defining.html#defining-units + + canonical_name = definition/base = unit symbol = alias 1 = alias 2 = ..." + "hour = 60 * minute = h = hr + second = [time] = s = sec + minute = 60 * second = min + millenium = 1e3 * year = _ = millenia + dog_year = 52 * day = dy") + +(deftest define-unit + (let [ureg (sut/make-unit-registry)] + (is (= {} (sut/define-unit ureg "dog_year = 52 * day = dy"))) + (is (= {} (sut/define-unit ureg "second = [time] = s = sec"))))) From 7aaf226dfd940b9e62c01acbd79a690fb2fc581d Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Tue, 21 Apr 2020 00:35:11 +0000 Subject: [PATCH 06/14] Runs cljfmt --- src/opengb/dram/core.cljc | 2 +- test/opengb/dram/registry_test.cljc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/opengb/dram/core.cljc b/src/opengb/dram/core.cljc index fb50554..322cdab 100644 --- a/src/opengb/dram/core.cljc +++ b/src/opengb/dram/core.cljc @@ -29,7 +29,7 @@ (get-unit [q])) (deftype quantity - [^:double mag unit] + [^:double mag unit] IQuantity (get-magnitude [q] (.-mag q)) (get-unit [q] (.-unit q))) diff --git a/test/opengb/dram/registry_test.cljc b/test/opengb/dram/registry_test.cljc index 102c2f0..04695c3 100644 --- a/test/opengb/dram/registry_test.cljc +++ b/test/opengb/dram/registry_test.cljc @@ -18,5 +18,5 @@ (deftest define-unit (let [ureg (sut/make-unit-registry)] - (is (= {} (sut/define-unit ureg "dog_year = 52 * day = dy"))) - (is (= {} (sut/define-unit ureg "second = [time] = s = sec"))))) + (is (= {} (sut/define-unit ureg "dog_year = 52 * day = dy"))) + (is (= {} (sut/define-unit ureg "second = [time] = s = sec"))))) From c19025f5bc84daab6900a97d38e7e7c0592593d0 Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Tue, 21 Apr 2020 01:11:10 +0000 Subject: [PATCH 07/14] Implements deftype equality, toString --- src/opengb/dram/core.cljc | 19 ++++++++++++++++--- test/opengb/dram/registry_test.cljc | 8 ++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/opengb/dram/core.cljc b/src/opengb/dram/core.cljc index 322cdab..2386580 100644 --- a/src/opengb/dram/core.cljc +++ b/src/opengb/dram/core.cljc @@ -18,9 +18,10 @@ #_(str ureg "\n" _unit-definition)) (defn valid-unit? - [_ureg _unit] - true ;; stubbed to test interface - #_(true? (get unit ureg))) + "Is the unit valid, or a combination of valid units?" + [_ureg unit] + ;; stubbed to test interface + (s/valid? ::unit unit)) ;; * quantities @@ -30,6 +31,12 @@ (deftype quantity [^:double mag unit] + Object + (equals [this other] + (and (= (get-magnitude this) (get-magnitude other)) + (= (get-unit this) (get-unit other)))) + (toString [q] + (str "<" (get-magnitude q) " " (get-unit q) ">")) IQuantity (get-magnitude [q] (.-mag q)) (get-unit [q] (.-unit q))) @@ -43,3 +50,9 @@ {:pre [(s/valid? ::magnitude mag) (valid-unit? unit-registry unit)]} (->quantity (double mag) unit)) + +;; * specs + +(s/def ::magnitude number?) + +(s/def ::unit string?) diff --git a/test/opengb/dram/registry_test.cljc b/test/opengb/dram/registry_test.cljc index 04695c3..59fbb72 100644 --- a/test/opengb/dram/registry_test.cljc +++ b/test/opengb/dram/registry_test.cljc @@ -20,3 +20,11 @@ (let [ureg (sut/make-unit-registry)] (is (= {} (sut/define-unit ureg "dog_year = 52 * day = dy"))) (is (= {} (sut/define-unit ureg "second = [time] = s = sec"))))) + +(deftest quantity-type-equality + (let [ureg (sut/make-unit-registry) + Q_ (partial sut/make-quantity ureg)] + (prn (Q_ 1.0 "m")) + (is (= (Q_ 1.0 "m") (Q_ 1.0 "m"))) + (is (not= (Q_ 1.0 "m") (Q_ 1.1 "m"))) + (is (not= (Q_ 1.0 "m") (Q_ 1.0 "ft"))))) From 16b868e7c962ba0f7c1103f43eedc66c8f9f22ad Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Tue, 21 Apr 2020 15:02:21 +0000 Subject: [PATCH 08/14] Make Quantity a capitalized type, per convention --- src/opengb/dram/core.cljc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/opengb/dram/core.cljc b/src/opengb/dram/core.cljc index 2386580..20389a7 100644 --- a/src/opengb/dram/core.cljc +++ b/src/opengb/dram/core.cljc @@ -29,7 +29,7 @@ (get-magnitude [q]) (get-unit [q])) -(deftype quantity +(deftype Quantity [^:double mag unit] Object (equals [this other] @@ -43,13 +43,13 @@ (defn quantity? [?q] - (= (type ?q) quantity)) + (= (type ?q) Quantity)) (defn make-quantity [unit-registry ^:double mag unit] {:pre [(s/valid? ::magnitude mag) (valid-unit? unit-registry unit)]} - (->quantity (double mag) unit)) + (->Quantity (double mag) unit)) ;; * specs From e56c64ff1c97a22a538e6151af791adff8bc638d Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Tue, 21 Apr 2020 15:04:19 +0000 Subject: [PATCH 09/14] Fixes object equality in cljs Seems we need to implement IEquiv as well for node + browser repl --- src/opengb/dram/core.cljc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/opengb/dram/core.cljc b/src/opengb/dram/core.cljc index 20389a7..7ecfa58 100644 --- a/src/opengb/dram/core.cljc +++ b/src/opengb/dram/core.cljc @@ -31,7 +31,7 @@ (deftype Quantity [^:double mag unit] - Object + Object ;; needs to be in deftype, else no protocol java.lang.Object (equals [this other] (and (= (get-magnitude this) (get-magnitude other)) (= (get-unit this) (get-unit other)))) @@ -41,6 +41,14 @@ (get-magnitude [q] (.-mag q)) (get-unit [q] (.-unit q))) +#?(:cljs + ;; not enough to do Object/equals in cljs?? + (extend-type Quantity + IEquiv + (-equiv [this other] + (and (= (get-magnitude this) (get-magnitude other)) + (= (get-unit this) (get-unit other)))))) + (defn quantity? [?q] (= (type ?q) Quantity)) From d6f42c80a9be9096f693ed6d94e1b5219304fba6 Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Tue, 21 Apr 2020 15:05:22 +0000 Subject: [PATCH 10/14] Make it clearer we're using a dummy registry in tests just now --- test/opengb/dram/registry_test.cljc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/opengb/dram/registry_test.cljc b/test/opengb/dram/registry_test.cljc index 59fbb72..c911040 100644 --- a/test/opengb/dram/registry_test.cljc +++ b/test/opengb/dram/registry_test.cljc @@ -3,8 +3,10 @@ [clojure.test :as t :refer [deftest is]] [opengb.dram.core :as sut])) +(def STUB-REGISTRY {}) + (deftest make-unit-registry - (is (= {} (sut/make-unit-registry)))) + (is (= STUB-REGISTRY (sut/make-unit-registry)))) (def time-definitions "See https://pint.readthedocs.io/en/0.10.1/defining.html#defining-units @@ -18,8 +20,8 @@ (deftest define-unit (let [ureg (sut/make-unit-registry)] - (is (= {} (sut/define-unit ureg "dog_year = 52 * day = dy"))) - (is (= {} (sut/define-unit ureg "second = [time] = s = sec"))))) + (is (= STUB-REGISTRY (sut/define-unit ureg "dog_year = 52 * day = dy"))) + (is (= STUB-REGISTRY (sut/define-unit ureg "second = [time] = s = sec"))))) (deftest quantity-type-equality (let [ureg (sut/make-unit-registry) From 679487744e7559bd8389dc6e261aae6b6c33f077 Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Tue, 21 Apr 2020 15:05:52 +0000 Subject: [PATCH 11/14] Stub in `define-prefix` For kilo, milli, etc. Following pint's definition convention. --- src/opengb/dram/core.cljc | 5 +++++ test/opengb/dram/registry_test.cljc | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/opengb/dram/core.cljc b/src/opengb/dram/core.cljc index 7ecfa58..71403b9 100644 --- a/src/opengb/dram/core.cljc +++ b/src/opengb/dram/core.cljc @@ -17,6 +17,11 @@ ureg ;; stubbed to test interface #_(str ureg "\n" _unit-definition)) +(defn define-prefix + [ureg _prefix-definition] + ureg ;; stubbed to test interface + ) + (defn valid-unit? "Is the unit valid, or a combination of valid units?" [_ureg unit] diff --git a/test/opengb/dram/registry_test.cljc b/test/opengb/dram/registry_test.cljc index c911040..09cd8fe 100644 --- a/test/opengb/dram/registry_test.cljc +++ b/test/opengb/dram/registry_test.cljc @@ -23,6 +23,10 @@ (is (= STUB-REGISTRY (sut/define-unit ureg "dog_year = 52 * day = dy"))) (is (= STUB-REGISTRY (sut/define-unit ureg "second = [time] = s = sec"))))) +(deftest define-prefix + (let [ureg (sut/make-unit-registry)] + (is (= STUB-REGISTRY (sut/define-prefix ureg "kilo- = 1e3 = k-"))))) + (deftest quantity-type-equality (let [ureg (sut/make-unit-registry) Q_ (partial sut/make-quantity ureg)] From df9f46ea727afe39312779d629de455a5e0f6a79 Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Tue, 28 Apr 2020 19:00:04 +0000 Subject: [PATCH 12/14] Removes spec dependency Just rely on the clojure one. --- deps.edn | 1 - 1 file changed, 1 deletion(-) diff --git a/deps.edn b/deps.edn index 8a13835..50e725d 100644 --- a/deps.edn +++ b/deps.edn @@ -1,7 +1,6 @@ {:paths ["src"] :deps {instaparse {:mvn/version "1.4.10"} org.clojure/clojure {:mvn/version "1.10.1"} - org.clojure/spec.alpha {:mvn/version "0.2.187"} org.clojure/test.check {:mvn/version "1.0.0"}} :aliases {:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.0-612"} lambdaisland/kaocha-cljs {:mvn/version "0.0-71"}} From 9ee7e00132be241f4a95a4d318ca7a011d5f3887 Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Wed, 29 Apr 2020 22:55:42 +0000 Subject: [PATCH 13/14] Fix equality to first make sure we can call IQuantity methods --- src/opengb/dram/core.cljc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/opengb/dram/core.cljc b/src/opengb/dram/core.cljc index 71403b9..3087ff6 100644 --- a/src/opengb/dram/core.cljc +++ b/src/opengb/dram/core.cljc @@ -38,10 +38,11 @@ [^:double mag unit] Object ;; needs to be in deftype, else no protocol java.lang.Object (equals [this other] - (and (= (get-magnitude this) (get-magnitude other)) + (and (satisfies? IQuantity other) + (= (get-magnitude this) (get-magnitude other)) (= (get-unit this) (get-unit other)))) (toString [q] - (str "<" (get-magnitude q) " " (get-unit q) ">")) + (str "<< " (get-magnitude q) " " (get-unit q) " >>")) IQuantity (get-magnitude [q] (.-mag q)) (get-unit [q] (.-unit q))) From df055aed7a3b8ee05530394b5923e43068125abd Mon Sep 17 00:00:00 2001 From: Ryan McCuaig Date: Tue, 26 May 2020 21:53:52 +0000 Subject: [PATCH 14/14] Add a guard on IEquiv Without this guard, clojurescript equality checks can blow up. --- src/opengb/dram/core.cljc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/opengb/dram/core.cljc b/src/opengb/dram/core.cljc index 3087ff6..a14f137 100644 --- a/src/opengb/dram/core.cljc +++ b/src/opengb/dram/core.cljc @@ -52,7 +52,8 @@ (extend-type Quantity IEquiv (-equiv [this other] - (and (= (get-magnitude this) (get-magnitude other)) + (and (satisfies? IQuantity other) + (= (get-magnitude this) (get-magnitude other)) (= (get-unit this) (get-unit other)))))) (defn quantity?