egison-5.1.0: lib/core/base.egi
--
--
-- Base
--
--
-- | Type class for equality
class Eq a where
(==) (x: a) (y: a) : Bool
(/=) (x: a) (y: a) : Bool
-- | Eq instances for basic types
instance Eq Integer where
(==) x y := x = y
(/=) x y := not (x == y)
instance Eq Float where
(==) x y := x = y
(/=) x y := not (x == y)
instance Eq String where
(==) x y := x = y
(/=) x y := not (x == y)
instance Eq Bool where
(==) x y := x = y
(/=) x y := not (x == y)
instance Eq Char where
(==) x y := x = y
(/=) x y := not (x == y)
instance {Eq a} Eq (Tensor a) where
(==) t1 t2 := t1 = t2
(/=) t1 t2 := not (t1 == t2)
def eq {Eq a} : Matcher a :=
matcher
| #$val as () with
| $tgt -> if val == tgt then [()] else []
| $ as something with
| $tgt -> [tgt]
-- The primitive matchers are eq's body inlined at each concrete type.
-- Matcher types are rigid (two different Matcher types never unify), so a
-- polymorphic matcher value cannot be specialized by annotation: `def
-- integer : Matcher Integer := eq` does not type-check, and an unannotated
-- alias `def integer := eq` would keep eq's polymorphic scheme, which a
-- concrete hole (e.g. `as (integer, ...)` at an Integer hole) rejects just
-- as it rejects `something`. A concrete matcher literal instead derives
-- its capability at the annotated type (T-MATCHER in checking mode).
-- The #$val arm uses the built-in equality `=` (same convention as
-- sortedList's #$val arm); for the base types it coincides with ==.
def bool : Matcher Bool :=
matcher
| #$val as () with
| $tgt -> if val = tgt then [()] else []
| $ as something with
| $tgt -> [tgt]
def char : Matcher Char :=
matcher
| #$val as () with
| $tgt -> if val = tgt then [()] else []
| $ as something with
| $tgt -> [tgt]
def integer : Matcher Integer :=
matcher
| #$val as () with
| $tgt -> if val = tgt then [()] else []
| $ as something with
| $tgt -> [tgt]
def float : Matcher Float :=
matcher
| #$val as () with
| $tgt -> if val = tgt then [()] else []
| $ as something with
| $tgt -> [tgt]
-- Additive hierarchy
class AddSemigroup a where
(+) (x: a) (y: a) : a
class AddMonoid a extends AddSemigroup a where
zero : a
class AddGroup a extends AddMonoid a where
neg (x: a) : a
-- Multiplicative hierarchy
class MulSemigroup a where
(*) (x: a) (y: a) : a
class MulMonoid a extends MulSemigroup a where
one : a
class MulGroup a extends MulMonoid a where
inv (x: a) : a
-- Composite structures
class Ring a extends AddGroup a, MulMonoid a
class Field a extends Ring a, MulGroup a
class GCDDomain a extends Ring a where
gcd (x: a) (y: a) : a
class EuclideanDomain a extends GCDDomain a where
divMod (x: a) (y: a) : (a, a)
-- Derived operators
def (-) {AddGroup a} (x: a) (y: a) : a := x + neg y
def (/) {Field a} (x: a) (y: a) : a := x * inv y
def modulo {EuclideanDomain a} (x: a) (y: a) : a := snd (divMod x y)
def quotient {EuclideanDomain a} (x: a) (y: a) : a := fst (divMod x y)
-- MathValue instances
instance AddSemigroup MathValue where
(+) x y := plusForMathValue x y
instance AddMonoid MathValue where
zero := 0
instance AddGroup MathValue where
neg x := minusForMathValue 0 x
instance MulSemigroup MathValue where
(*) x y := multForMathValue x y
instance MulMonoid MathValue where
one := 1
instance MulGroup MathValue where
inv x := divForMathValue 1 x
instance Ring MathValue
instance Field MathValue
instance GCDDomain MathValue where
gcd x y := gcdForMathValue x y
instance EuclideanDomain MathValue where
divMod x y := (i.quotient x y, i.modulo x y)
-- Float instances
instance AddSemigroup Float where
(+) x y := f.+ x y
instance AddMonoid Float where
zero := 0.0
instance AddGroup Float where
neg x := f.- 0.0 x
instance MulSemigroup Float where
(*) x y := f.* x y
instance MulMonoid Float where
one := 1.0
instance MulGroup Float where
inv x := f./ 1.0 x
instance Ring Float
instance Field Float
--
-- CAS type widening / narrowing
--
-- After Phase C, both `Embed` and the `coerceTo*` helper functions have been
-- removed in favor of the unified `reshape` mechanism: the type checker
-- inserts a `TIReshape T` node whenever a `def x : T := e` annotation is
-- encountered (where T is a concrete CAS scalar — Integer, Factor, Frac _,
-- Poly _ _, Term _ _). At runtime, `casReshapeAs T v` structurally rewrites
-- the CAS value to fit T (collapsing Frac with denom=1 to Integer, lifting
-- Integer into Poly form, etc.).
--
-- Subtype unification handles the static side (Integer ⊂ Frac Integer ⊂
-- Poly Integer [..] ⊂ Poly (Frac Integer) [..] ⊂ Frac (Poly Integer [..])).
-- Together this gives "trust the annotation" semantics:
--
-- def n : Integer := someExpr -- reshapes runtime to Integer
-- def p : Poly Integer [x,y] := someExpr -- reshapes to specific atom set
-- def t : Term MathValue [..]:= someExpr -- reshapes to single-term form
--
--
-- Rule application combinators (Phase 7.5 helper)
--
-- `applyRules` runs each rule once, left-to-right. `iterateRules` runs
-- the chain repeatedly until the value stops changing (fixed point).
-- Users hand-build the rule list from `rule.<name>` references.
--
def applyRules {a} (rules : [a -> a]) (v : a) : a :=
foldl (\acc r -> r acc) v rules
def iterateRules {Eq a} (rules : [a -> a]) (v : a) : a :=
let v' := applyRules rules v
in if v == v' then v else iterateRules rules v'
--
-- Utility
--
def id {a} (x: a) : a := x
def fst {a, b} (x: a, _: b) : a := x
def snd {a, b} (_: a, y: b) : b := y
def ($) {a, b} (f: a -> b) (x: a) : b := f x
def compose {a, b, c} (f: a -> b) (g: b -> c) : a -> c := \x -> g (f x)
def flip {a, b, c} (fn: a -> b -> c) : b -> a -> c := \x y -> fn y x
def eqAs {a} (m: MatcherSlot a a) (x: a) (y: a) : Bool :=
match x as m with
| #y -> True
| _ -> False
def curry {a, b, c} (f: (a, b) -> c) (x: a) (y: b) : c := f (x, y)
def uncurry {a, b, c} (f: a -> b -> c) (x: a, y: b) : c := f x y
--
-- Boolean
--
def (&&) (b1: Bool) (b2: Bool) : Bool := if b1 then b2 else False
def (||) (b1: Bool) (b2: Bool) : Bool := if b1 then True else b2
def not (b: Bool) : Bool := if b then False else True
--
-- Unordered Pair
--
def unorderedPair {a} (m: MatcherSlot a a) : Matcher (a, a) :=
matcher
| ($, $) as (m, m) with
| ($x, $y) -> [(x, y), (y, x)]
| $ as something with
| $tgt -> [tgt]