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
No related tags found
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