-
Notifications
You must be signed in to change notification settings - Fork 0
/
divide.go
122 lines (105 loc) · 3.33 KB
/
divide.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package suiron
// Divide
//
// A built-in function to divide numbers. Eg.:
//
// $X = divide(7, 3, 2),... // (7 / 3 / 2)
//
// Divide always produces a floating point number.
//
// Cleve Lendon
import (
"fmt"
)
type DivideStruct BuiltInPredicateStruct
// Divide - creates a DivideStruct, which holds the function's
// name and arguments. Divide requires at least 2 arguments.
// Params: arguments (Unifiable)
// Return: DivideStruct
func Divide(arguments ...Unifiable) DivideStruct {
if len(arguments) < 2 {
panic("Divide - requires at least 2 arguments.")
}
return DivideStruct {
Name: "divide",
Arguments: arguments,
}
}
//----------------------------------------------------------------
// bifDivide - Divides all arguments together.
// All arguments must be bound.
//
// Params:
// list of arguments
// substitution set
// Returns:
// new unifiable
// success/failure flag
//
func bifDivide(arguments []Unifiable, ss SubstitutionSet) (Unifiable, bool) {
ground := []Unifiable{} // Array of ground terms.
// Get ground terms.
for _, arg := range arguments {
c, ok := ss.GetGroundTerm(arg)
if !ok {
s := fmt.Sprintf("Divide - Argument is not ground: %v", arg)
panic(s)
}
ground = append(ground, c)
}
var result Float
arg := ground[0]
tt := arg.TermType()
if tt == INTEGER {
result = Float(arg.(Integer))
} else {
result = arg.(Float)
}
for n, arg := range ground {
if n == 0 { continue }
tt = arg.TermType()
if tt == INTEGER {
result /= Float(arg.(Integer))
} else {
result /= arg.(Float)
}
}
return Unifiable(result), true
} // bifDivide
//----------------------------------------------------------------
// RecreateVariables(), ReplaceVariables(), and String() satisfy
// the Expression interface.
//----------------------------------------------------------------
// RecreateVariables - Refer to comments in expression.go.
func (ms DivideStruct) RecreateVariables(vars VarMap) Expression {
bif := BuiltInPredicateStruct(ms).RecreateVariables(vars)
return Expression(DivideStruct(*bif))
}
// ReplaceVariables - Refer to comments in expression.go.
func (ms DivideStruct) ReplaceVariables(ss SubstitutionSet) Expression {
return BuiltInPredicateStruct(ms).ReplaceVariables(ss)
} // ReplaceVariables
// String - creates a string representation.
// Returns: function_name(arg1, arg2, arg3)
func (ms DivideStruct) String() string {
return BuiltInPredicateStruct(ms).String()
}
//----------------------------------------------------------------
// Unify() and TermType() satisfy the Unifiable interface.
//----------------------------------------------------------------
// Unify - unifies the result of a function with another term
// (usually a variable).
//
// Params:
// other unifiable term
// substitution set
// Returns:
// updated substitution set
// success/failure flag
func (as DivideStruct) Unify(other Unifiable, ss SubstitutionSet) (SubstitutionSet, bool) {
result, ok := bifDivide(as.Arguments, ss)
if !ok { return ss, false }
return result.Unify(other, ss)
}
// TermType - returns a constant which identifies this type.
func (as DivideStruct) TermType() int { return FUNCTION }