mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 03:32:51 -06:00
overload rules and their documentation
This commit is contained in:
@@ -14,6 +14,33 @@ Changes in functionality since May 17, 2005, release of GF Version 2.2
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
|
21/12 (AR) Overloading rules for GF version 2.7:
|
||||||
|
<ol>
|
||||||
|
<li> If a unique instance is found by exact match with argument types,
|
||||||
|
that instance is used.
|
||||||
|
<li> Otherwise, if exact match with the expected value type gives a
|
||||||
|
uniques instance, that instance is used.
|
||||||
|
<li> Otherwise, if among possible instances only one returns a non-function
|
||||||
|
type, that instance is used, but a warning is issued.
|
||||||
|
<li> Otherwise, an error results, and the list of possible instances is shown.
|
||||||
|
</ol>
|
||||||
|
These rules are still temporary, but all future developments will guarantee
|
||||||
|
that their type-correct use will work. Rule (3) is only needed because the
|
||||||
|
current type checker does not always know an expected type. It can give
|
||||||
|
an incorrect result which is captured later in the compilation. To be noticed,
|
||||||
|
in particular, is that exact match is required. Match by subtyping will be
|
||||||
|
investigated later.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
20/11 (AR) Type error messages in concrete syntax are printed with a
|
||||||
|
heuristic where a type of the form <tt>{... ; lock_C : {} ; ...}</tt>
|
||||||
|
is printed as <tt>C</tt>. This gives more readable error messages, but
|
||||||
|
can produce wrong results if lock fields are hand-written or if subtypes
|
||||||
|
of lock-fielded categories are used.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
17/11 (AR) Operation overloading: an <tt>oper</tt> can have many types,
|
17/11 (AR) Operation overloading: an <tt>oper</tt> can have many types,
|
||||||
from which one is picked at compile time. The types must have different
|
from which one is picked at compile time. The types must have different
|
||||||
argument lists. Exact match with the arguments given to the <tt>oper</tt>
|
argument lists. Exact match with the arguments given to the <tt>oper</tt>
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ lin
|
|||||||
|
|
||||||
one = UsePN (regPN "one") ;
|
one = UsePN (regPN "one") ;
|
||||||
two = UsePN (regPN "two") ;
|
two = UsePN (regPN "two") ;
|
||||||
sum = appColl (regN2 "sum") ;
|
sum = app (regN2 "sum") ;
|
||||||
prod = appColl (regN2 "product") ;
|
prod = app (regN2 "product") ;
|
||||||
|
|
||||||
evax1 =
|
evax1 =
|
||||||
proof (by (ref (mkLabel ["the first axiom of evenness ,"])))
|
proof (by (ref (mkLabel ["the first axiom of evenness ,"])))
|
||||||
@@ -42,14 +42,14 @@ lin
|
|||||||
|
|
||||||
eqax1 =
|
eqax1 =
|
||||||
proof (by (ref (mkLabel ["the first axiom of equality ,"])))
|
proof (by (ref (mkLabel ["the first axiom of equality ,"])))
|
||||||
(mkS (predA2 (mkA2 (regA "equal") (mkPrep "to"))
|
(mkS (pred (mkA2 (regA "equal") (mkPrep "to"))
|
||||||
(UsePN (regPN "zero"))
|
(UsePN (regPN "zero"))
|
||||||
(UsePN (regPN "zero")))) ;
|
(UsePN (regPN "zero")))) ;
|
||||||
|
|
||||||
eqax2 m n c =
|
eqax2 m n c =
|
||||||
appendText c
|
appendText c
|
||||||
(proof (by (ref (mkLabel ["the second axiom of equality ,"])))
|
(proof (by (ref (mkLabel ["the second axiom of equality ,"])))
|
||||||
(mkS (predA2 (mkA2 (regA "equal") (mkPrep "to"))
|
(mkS (pred (mkA2 (regA "equal") (mkPrep "to"))
|
||||||
(appN2 (regN2 "successor") m) (appN2 (regN2 "successor") n)))) ;
|
(appN2 (regN2 "successor") m) (appN2 (regN2 "successor") n)))) ;
|
||||||
|
|
||||||
IndNat C d e = {s =
|
IndNat C d e = {s =
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ lin
|
|||||||
Univ A B =
|
Univ A B =
|
||||||
AdvS
|
AdvS
|
||||||
(mkAdv for_Prep (mkNP all_Predet
|
(mkAdv for_Prep (mkNP all_Predet
|
||||||
(mkNP (mkDet (PlQuant IndefArt) NoNum NoOrd) (mkCN A (symb B.$0)))))
|
(mkNP (mkDet (PlQuant IndefArt)) (mkCN A (symb B.$0)))))
|
||||||
B ;
|
B ;
|
||||||
|
|
||||||
DisjIl A B a = proof a (proof afortiori (coord or_Conj A B)) ;
|
DisjIl A B a = proof a (proof afortiori (coord or_Conj A B)) ;
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ oper
|
|||||||
proof : Decl -> Proof
|
proof : Decl -> Proof
|
||||||
= \d -> d ;
|
= \d -> d ;
|
||||||
proof : Proof -> Proof -> Proof
|
proof : Proof -> Proof -> Proof
|
||||||
= \p,q -> appendText p q ;
|
= appendText ;
|
||||||
proof : Branching -> Proofs -> Proof
|
proof : Branching -> Proofs -> Proof
|
||||||
= \b,ps -> mkText (mkPhr b) ps
|
= \b,ps -> mkText (mkPhr b) ps
|
||||||
} ;
|
} ;
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ checkResInfo gr mo (c,info) = do
|
|||||||
checkUniq xss = case xss of
|
checkUniq xss = case xss of
|
||||||
x:y:xs
|
x:y:xs
|
||||||
| x == y -> raise $ "ambiguous for argument list" +++
|
| x == y -> raise $ "ambiguous for argument list" +++
|
||||||
unwords (map prtType x)
|
unwords (map (prtType gr) x)
|
||||||
| otherwise -> checkUniq $ y:xs
|
| otherwise -> checkUniq $ y:xs
|
||||||
_ -> return ()
|
_ -> return ()
|
||||||
|
|
||||||
@@ -412,7 +412,7 @@ inferLType gr trm = case trm of
|
|||||||
else substituteLType [(z,a')] val
|
else substituteLType [(z,a')] val
|
||||||
return (App f' a',ty)
|
return (App f' a',ty)
|
||||||
_ -> raise ("function type expected for"+++
|
_ -> raise ("function type expected for"+++
|
||||||
prt f +++"instead of" +++ prtType fty)
|
prt f +++"instead of" +++ prtType env fty)
|
||||||
|
|
||||||
S f x -> do
|
S f x -> do
|
||||||
(f', fty) <- infer f
|
(f', fty) <- infer f
|
||||||
@@ -596,14 +596,22 @@ getOverload env@gr mt t = case appForm t of
|
|||||||
case [vf | vf@(v,f) <- vfs, elem mt [Nothing,Just v]] of
|
case [vf | vf@(v,f) <- vfs, elem mt [Nothing,Just v]] of
|
||||||
[(val,fun)] -> return (mkApp fun tts, val)
|
[(val,fun)] -> return (mkApp fun tts, val)
|
||||||
[] -> raise $ "no overload instance of" +++ prt f +++
|
[] -> raise $ "no overload instance of" +++ prt f +++
|
||||||
maybe [] (("when expecting" +++) . prtType) mt +++
|
maybe [] (("when expecting" +++) . prtType env) mt +++
|
||||||
"for" +++ unwords (map prtType tys) +++ "among" ++++
|
"for" +++ unwords (map (prtType env) tys) +++ "among" ++++
|
||||||
unlines [unwords (map prtType ty) | (ty,_) <- typs]
|
unlines [unwords (map (prtType env) ty) | (ty,_) <- typs]
|
||||||
---- ++++ "DEBUG" +++ unwords (map show tys) +++ ";"
|
---- ++++ "DEBUG" +++ unwords (map show tys) +++ ";"
|
||||||
---- ++++ unlines (map (show . fst) typs) ----
|
---- ++++ unlines (map (show . fst) typs) ----
|
||||||
_ -> raise $ "ambiguous overloading of" +++ prt f +++
|
|
||||||
"for" +++ unwords (map prtType tys) ++++ "with alternatives" ++++
|
vfs' -> case [(v,f) | (v,f) <- vfs', noProd v] of
|
||||||
unlines [prtType ty | (ty,_) <- vfs]
|
[(val,fun)] -> do
|
||||||
|
checkWarn $ "WARNING: overloading of" +++ prt f +++
|
||||||
|
"resolved by excluding partial applications:" ++++
|
||||||
|
unlines [prtType env ty | (ty,_) <- vfs', not (noProd ty)]
|
||||||
|
return (mkApp fun tts, val)
|
||||||
|
|
||||||
|
_ -> raise $ "ambiguous overloading of" +++ prt f +++
|
||||||
|
"for" +++ unwords (map (prtType env) tys) ++++ "with alternatives" ++++
|
||||||
|
unlines [prtType env ty | (ty,_) <- vfs']
|
||||||
|
|
||||||
---- TODO: accept subtypes
|
---- TODO: accept subtypes
|
||||||
---- TODO: use a trie
|
---- TODO: use a trie
|
||||||
@@ -614,6 +622,9 @@ getOverload env@gr mt t = case appForm t of
|
|||||||
pre == tys
|
pre == tys
|
||||||
]
|
]
|
||||||
|
|
||||||
|
noProd ty = case ty of
|
||||||
|
Prod _ _ _ -> False
|
||||||
|
_ -> True
|
||||||
|
|
||||||
checkLType :: SourceGrammar -> Term -> Type -> Check (Term, Type)
|
checkLType :: SourceGrammar -> Term -> Type -> Check (Term, Type)
|
||||||
checkLType env trm typ0 = do
|
checkLType env trm typ0 = do
|
||||||
@@ -633,7 +644,7 @@ checkLType env trm typ0 = do
|
|||||||
check c b'
|
check c b'
|
||||||
checkReset
|
checkReset
|
||||||
return $ (Abs x c', Prod x a b')
|
return $ (Abs x c', Prod x a b')
|
||||||
_ -> raise $ "product expected instead of" +++ prtType typ
|
_ -> raise $ "product expected instead of" +++ prtType env typ
|
||||||
|
|
||||||
App f a -> do
|
App f a -> do
|
||||||
over <- getOverload env (Just typ) trm
|
over <- getOverload env (Just typ) trm
|
||||||
@@ -659,7 +670,7 @@ checkLType env trm typ0 = do
|
|||||||
_ -> return () -- happens with variable types
|
_ -> return () -- happens with variable types
|
||||||
cs' <- mapM (checkCase arg val) cs
|
cs' <- mapM (checkCase arg val) cs
|
||||||
return (T (TTyped arg) cs', typ)
|
return (T (TTyped arg) cs', typ)
|
||||||
_ -> raise $ "table type expected for table instead of" +++ prtType typ
|
_ -> raise $ "table type expected for table instead of" +++ prtType env typ
|
||||||
|
|
||||||
R r -> case typ of --- why needed? because inference may be too difficult
|
R r -> case typ of --- why needed? because inference may be too difficult
|
||||||
RecType rr -> do
|
RecType rr -> do
|
||||||
@@ -715,7 +726,7 @@ checkLType env trm typ0 = do
|
|||||||
checkEq typ t trm
|
checkEq typ t trm
|
||||||
return (S tab' arg', t)
|
return (S tab' arg', t)
|
||||||
_ -> raise $ "table type expected for applied table instead of" +++
|
_ -> raise $ "table type expected for applied table instead of" +++
|
||||||
prtType ty'
|
prtType env ty'
|
||||||
, do
|
, do
|
||||||
(arg',ty) <- infer arg
|
(arg',ty) <- infer arg
|
||||||
ty' <- comp ty
|
ty' <- comp ty
|
||||||
@@ -844,21 +855,26 @@ check2 chk con a b t = do
|
|||||||
|
|
||||||
checkEqLType :: LTEnv -> Type -> Type -> Term -> Check Type
|
checkEqLType :: LTEnv -> Type -> Type -> Term -> Check Type
|
||||||
checkEqLType env t u trm = do
|
checkEqLType env t u trm = do
|
||||||
|
(b,t',u',s) <- checkIfEqLType env t u trm
|
||||||
|
case b of
|
||||||
|
True -> return t'
|
||||||
|
False -> raise $ s +++ "type of" +++ prt trm +++
|
||||||
|
": expected:" +++ prtType env t ++++
|
||||||
|
"inferred:" +++ prtType env u
|
||||||
|
|
||||||
|
checkIfEqLType :: LTEnv -> Type -> Type -> Term -> Check (Bool,Type,Type,String)
|
||||||
|
checkIfEqLType env t u trm = do
|
||||||
t' <- comp t
|
t' <- comp t
|
||||||
u' <- comp u
|
u' <- comp u
|
||||||
case t' == u' || alpha [] t' u' of
|
case t' == u' || alpha [] t' u' of
|
||||||
True -> return t'
|
True -> return (True,t',u',[])
|
||||||
-- forgive missing lock fields by only generating a warning.
|
-- forgive missing lock fields by only generating a warning.
|
||||||
--- better: use a flag to forgive? (AR 31/1/2006)
|
--- better: use a flag to forgive? (AR 31/1/2006)
|
||||||
_ -> case missingLock [] t' u' of
|
_ -> case missingLock [] t' u' of
|
||||||
Ok lo -> do
|
Ok lo -> do
|
||||||
checkWarn $ "WARNING: missing lock field" +++ unwords (map prt lo)
|
checkWarn $ "WARNING: missing lock field" +++ unwords (map prt lo)
|
||||||
return t'
|
return (True,t',u',[])
|
||||||
Bad s -> raise (s +++ "type of" +++ prt trm +++
|
Bad s -> return (False,t',u',s)
|
||||||
": expected:" +++ prtType t' ++++
|
|
||||||
"inferred:" +++ prtType u'
|
|
||||||
---- +++++ "DEBUG:" ++++ show t' ++++ show u'
|
|
||||||
)
|
|
||||||
where
|
where
|
||||||
|
|
||||||
-- t is a subtype of u
|
-- t is a subtype of u
|
||||||
@@ -920,13 +936,17 @@ checkEqLType env t u trm = do
|
|||||||
comp = computeLType env
|
comp = computeLType env
|
||||||
|
|
||||||
-- printing a type with a lock field lock_C as C
|
-- printing a type with a lock field lock_C as C
|
||||||
prtType :: Type -> String
|
prtType :: LTEnv -> Type -> String
|
||||||
prtType ty = case ty of
|
prtType env ty = case ty of
|
||||||
RecType fs -> case filter isLockLabel $ map fst fs of
|
RecType fs -> case filter isLockLabel $ map fst fs of
|
||||||
[lock] -> (drop 5 $ prt lock) --- ++++ "Full form" +++ prt ty
|
[lock] -> (drop 5 $ prt lock) --- ++++ "Full form" +++ prt ty
|
||||||
_ -> prt ty
|
_ -> prtt ty
|
||||||
Prod x a b -> prtType a +++ "->" +++ prtType b
|
Prod x a b -> prtType env a +++ "->" +++ prtType env b
|
||||||
_ -> prt ty
|
_ -> prtt ty
|
||||||
|
where
|
||||||
|
prtt t = prt t
|
||||||
|
---- use computeLType gr to check if really equal to the cat with lock
|
||||||
|
|
||||||
|
|
||||||
-- | linearization types and defaults
|
-- | linearization types and defaults
|
||||||
linTypeOfType :: SourceGrammar -> Ident -> Type -> Check (Context,Type)
|
linTypeOfType :: SourceGrammar -> Ident -> Type -> Check (Context,Type)
|
||||||
|
|||||||
Reference in New Issue
Block a user