-- ==========================================================--
-- === Constructor functions ===--
-- === Constructors.hs ===--
-- ==========================================================--
module Constructors where
import BaseDefs
import Utils
import MyUtils
import DomainExpr
import AbstractVals2
import SuccsAndPreds2
import AbstractMisc
import Inverse
import Apply
-- ==========================================================--
--
coMakeConstructorInstance :: Bool -> -- True == use mindless inverse
[ConstrElem] -> -- tells about constructor args
DExpr -> -- simplest instance expression
DSubst -> -- domain of use
Route
coMakeConstructorInstance mi cargs simplest_init usage
= let
----------------------------------------------------------------
-- Find out whether the constructor has zero arity, and --
-- prepare a relevant domain expression for it. --
----------------------------------------------------------------
(doCAFkludge, simplest)
= case simplest_init of
dx@(DXFunc _ _) -> (False, dx)
dx_CAF -> (True, DXFunc [] dx_CAF)
----------------------------------------------------------------
-- Find out if it is a recursive type. --
----------------------------------------------------------------
recursive
= case simplest of
DXFunc _ (DXLift1 _) -> False
DXFunc _ (DXLift2 _) -> True
anythingElse -> panic "coMakeConstructorInstance:recursive"
actual
= dxApplyDSubst usage simplest
(actualSources, actualTarget)
= case actual of Func dss dt -> (dss, dt)
----------------------------------------------------------------
-- --
----------------------------------------------------------------
(target_domain_products, points_below_structure_point)
= case (recursive, actualTarget) of
(True, Lift2 dts) -> (dts, [Stop2, Up2])
(True, Lift1 [Two]) -> (panic "cMCI(1)", [Stop1, Up1 [Zero]])
(False, Lift1 dts) -> (dts, [Stop1])
(False, Two) -> (panic "cMCI(2)", [Zero])
all_product_points
= myCartesianProduct (map amAllRoutes target_domain_products)
points_not_below_structure_point
= case (recursive, actualTarget) of
(True, Lift2 dts) -> map UpUp2 all_product_points
(True, Lift1 [Two]) -> [Up1 [One]]
(False, Lift1 dts) -> map Up1 all_product_points
(False, Two) -> [One]
tagTable
= [(p, arg_bottoms)
| p <- points_below_structure_point] ++
[(p, [MkFrel (map (magic p) cargs)])
| p <- points_not_below_structure_point]
arg_bottoms
= [MkFrel (map avBottomR actualSources)]
----------------------------------------------------------------
-- --
----------------------------------------------------------------
magic p ConstrRec = p
magic p (ConstrVar n) = xpts p ## n
xpts p
| recursive = case p of UpUp2 rs -> rs
| otherwise = case p of Up1 rs -> rs
----------------------------------------------------------------
-- --
----------------------------------------------------------------
in
if doCAFkludge
then apPapConst (coCGen_aux mi tagTable actual)
else Rep (coCGen_aux mi tagTable actual)
-- ==========================================================--
--
coCGen_aux :: Bool ->
AList Route [FrontierElem] -> -- the tag/value table
Domain -> -- domain of the function to be made
Rep
coCGen_aux mi tt (Func dss Two)
= let f1 = sort (utSureLookup tt "coCGen_aux(1)" One)
f0 = spMax0FromMin1 dss f1
ar = case head (f1 ++ f0) of MkFrel fels -> length fels
in RepTwo (Min1Max0 ar f1 f0)
coCGen_aux mi tt (Func dss (Lift1 dts))
= let lf_f1 = sort (utSureLookup tt "coCGen_aux(2)" (Up1 (map avBottomR dts)))
lf_f0 = spMax0FromMin1 dss lf_f1
lf_ar = length dss
newtt = [(rs, fels) | (Up1 rs, fels) <- tt]
in
Rep1 (Min1Max0 lf_ar lf_f1 lf_f0)
(coCGen_aux_cross mi newtt dss dts)
coCGen_aux mi tt (Func dss (Lift2 dts))
= let lf_f1 = sort (utSureLookup tt "coCGen_aux(2)" Up2)
lf_f0 = spMax0FromMin1 dss lf_f1
mf_f1 = sort (utSureLookup tt "coCGen_aux(3)" (UpUp2 (map avBottomR dts)))
mf_f0 = spMax0FromMin1 dss mf_f1
lf_ar = length dss
newtt = [(rs, fels) | (UpUp2 rs, fels) <- tt]
in
Rep2 (Min1Max0 lf_ar lf_f1 lf_f0)
(Min1Max0 lf_ar mf_f1 mf_f0)
(coCGen_aux_cross mi newtt dss dts)
coCGen_aux mi tt (Func dss gDomain@(Func dss2 dt))
= let newtt = map makenewtt (amAllRoutes dt)
makenewtt x
= (x,
avMinfrel [MkFrel (xs++ys)
| (g, min_args_to_get_g) <- tt,
MkFrel xs <- min_args_to_get_g,
MkFrel ys <- inMinInverse mi gDomain g x] )
-- *** don't know if the avMinfrel is really necessary *** --
in coCGen_aux mi newtt (Func (dss++dss2) dt)
-- ==========================================================--
--
coCGen_aux_cross :: Bool ->
AList [Route] [FrontierElem] ->
[Domain] ->
[Domain] ->
[Rep]
coCGen_aux_cross mi tt dss dts
= let numberOfDimensions
= length dts
doOneDimension n
= coCGen_aux mi (fixtt n) (Func dss (dts ## n))
--- ** DENORMALISATION ** ---
fixtt n
= let thisDimPoints
= taddall [] tt
taddall acc []
= acc
taddall acc ((rs,fel):rest)
= taddall (tadd (rs ## n) fel acc) rest
tadd :: Route ->
[FrontierElem] ->
AList Route [[FrontierElem]] ->
AList Route [[FrontierElem]]
tadd r fel []
= [(r, [fel])]
tadd r fel (this@(rr, fels):rest)
| r == rr = (rr, fel:fels):rest
| otherwise = this : tadd r fel rest
fixedtt
= map2nd
(foldr avLUBmin1frontier [MkFrel (map avTopR dss)])
thisDimPoints
in
fixedtt
in
map doOneDimension (0 `myIntsFromTo` (numberOfDimensions-1))
-- ==========================================================--
-- === end Constructors.hs ===--
-- ==========================================================--
|