Skip to content
Snippets Groups Projects
Unverified Commit 1ee2a5bb authored by Kevin Lyda's avatar Kevin Lyda
Browse files

Add convert rules.

parent e0bca4bf
No related branches found
Tags v1.20140508-1
No related merge requests found
...@@ -3,6 +3,7 @@ package rules ...@@ -3,6 +3,7 @@ package rules
import ( import (
"errors" "errors"
"fmt"
"github.com/ichiban/prolog" "github.com/ichiban/prolog"
) )
...@@ -14,6 +15,9 @@ type Engine struct { ...@@ -14,6 +15,9 @@ type Engine struct {
var ( var (
prologKinds = ` prologKinds = `
unit_kind(f, temperature).
unit_kind(k, temperature).
unit_kind(c, temperature).
unit_kind(m2, area). unit_kind(m2, area).
unit_kind(cm2, area). unit_kind(cm2, area).
unit_kind(cm, distance). unit_kind(cm, distance).
...@@ -28,9 +32,22 @@ var ( ...@@ -28,9 +32,22 @@ var (
unit_kind(butter, density). unit_kind(butter, density).
unit_kind(water, density). unit_kind(water, density).
` `
prologKindsConvert = ` prologConvert = `
convert_kind(mass, volume, density). rule(GivenQuant, f, TargetQuant, c) :-
convert_kind(volume, area, distance). TargetQuant is (GivenQuant - 32) * 5 / 9.
rule(GivenQuant, c, TargetQuant, f) :-
TargetQuant is (GivenQuant / 5 * 9) + 32.
rule(GivenQuant, c, TargetQuant, k) :-
TargetQuant is GivenQuant + 273.15.
rule(GivenQuant, k, TargetQuant, c) :-
TargetQuant is GivenQuant - 273.15.
rule(GivenQuant, GivenUnit, TargetQuant, TargetUnit) :-
rule(GivenQuant, GivenUnit, X, Y),
rule(X, Y, TargetQuant, TargetUnit).
convert(GivenQuant, GivenUnit, TargetQuant, TargetUnit) :-
unit_kind(GivenUnit, temperature),
unit_kind(TargetUnit, temperature),
rule(GivenQuant, GivenUnit, TargetQuant, TargetUnit).
` `
) )
...@@ -48,6 +65,10 @@ func New() (*Engine, error) { ...@@ -48,6 +65,10 @@ func New() (*Engine, error) {
return nil, err return nil, err
} }
if err := ngn.p.Exec(prologConvert); err != nil {
return nil, err
}
return ngn, nil return ngn, nil
} }
...@@ -74,3 +95,25 @@ func (ngn *Engine) Kind(unit string) (string, error) { ...@@ -74,3 +95,25 @@ func (ngn *Engine) Kind(unit string) (string, error) {
} }
return result, nil return result, nil
} }
// Convert converts units.
func (ngn *Engine) Convert(qty float64, givenUnit, targetUnit string) (float64, error) {
sols, err := ngn.p.Query("convert(?, ?, Qty, ?).", qty, givenUnit, targetUnit)
if err != nil {
fmt.Println("Huh?")
return 0, err
}
defer sols.Close()
for sols.Next() {
var quantity struct {
Qty float64
}
if err := sols.Scan(&quantity); err != nil {
fmt.Println("Scan?")
return 0, err
}
return quantity.Qty, err
}
return 0, err
}
...@@ -30,3 +30,32 @@ func TestKinds(t *testing.T) { ...@@ -30,3 +30,32 @@ func TestKinds(t *testing.T) {
}) })
} }
} }
func TestConverts(t *testing.T) {
cases := []struct {
name string
qty float64
given string
target string
result float64
}{
{
"c to f",
22.0,
"c",
"f",
71.6,
},
}
ngn, err := New()
assert.NoError(t, err)
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
result, err := ngn.Convert(tc.qty, tc.given, tc.target)
assert.NoError(t, err)
assert.InDelta(t, tc.result, result, 0.1)
})
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment