aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'frontend')
-rw-r--r--frontend/checktypes.icl16
-rw-r--r--frontend/frontend.dcl2
-rw-r--r--frontend/frontend.icl2
-rw-r--r--frontend/main.icl2
-rw-r--r--frontend/syntax.dcl4
-rw-r--r--frontend/syntax.icl16
-rw-r--r--frontend/type.dcl2
-rw-r--r--frontend/type.icl27
-rw-r--r--frontend/typesupport.dcl35
-rw-r--r--frontend/typesupport.icl371
10 files changed, 424 insertions, 53 deletions
diff --git a/frontend/checktypes.icl b/frontend/checktypes.icl
index b063707..e681d85 100644
--- a/frontend/checktypes.icl
+++ b/frontend/checktypes.icl
@@ -950,22 +950,6 @@ checkSpecialTypes mod_index SP_None type_defs modules heaps cs
= (SP_None, type_defs, modules, heaps, cs)
-/* MW: already defined in module syntax
-instance <<< SelectorDef
-where
- (<<<) file {sd_symb} = file <<< sd_symb
-*/
-
-instance <<< AttrInequality
-where
- (<<<) file {ai_demanded,ai_offered}
- = file <<< ai_offered <<< " <= " <<< ai_demanded
-/*
-instance <<< VarBind
-where
- (<<<) file vb = file <<< (vb.vb_var,vb.vb_vars)
-*/
-
cOuterMostLevel :== 0
addTypeVariablesToSymbolTable :: ![ATypeVar] ![AttributeVar] !*TypeHeaps !*CheckState
diff --git a/frontend/frontend.dcl b/frontend/frontend.dcl
index 712ebb4..941dcdd 100644
--- a/frontend/frontend.dcl
+++ b/frontend/frontend.dcl
@@ -25,5 +25,5 @@ import checksupport, transform, overloading
| FrontEndPhaseConvertModules
| FrontEndPhaseAll
-frontEndInterface :: !FrontEndPhase !Ident !SearchPaths !Bool !*PredefinedSymbols !*HashTable !*Files !*File !*File !*File -> (!*PredefinedSymbols, !*HashTable, !*Files, !*File, !*File, !*File, !Optional *FrontEndSyntaxTree)
+frontEndInterface :: !FrontEndPhase !Ident !SearchPaths !(Optional Bool) !*PredefinedSymbols !*HashTable !*Files !*File !*File !*File -> (!*PredefinedSymbols, !*HashTable, !*Files, !*File, !*File, !*File, !Optional *FrontEndSyntaxTree)
// upToPhase name paths list_inferred_types predefs files error io out \ No newline at end of file
diff --git a/frontend/frontend.icl b/frontend/frontend.icl
index 255b752..98af8c2 100644
--- a/frontend/frontend.icl
+++ b/frontend/frontend.icl
@@ -78,7 +78,7 @@ instance == FrontEndPhase where
(==) a b
= equal_constructor a b
-frontEndInterface :: !FrontEndPhase !Ident !SearchPaths !Bool !*PredefinedSymbols !*HashTable !*Files !*File !*File !*File -> (!*PredefinedSymbols, !*HashTable, !*Files, !*File, !*File, !*File, !Optional *FrontEndSyntaxTree)
+frontEndInterface :: !FrontEndPhase !Ident !SearchPaths !(Optional Bool) !*PredefinedSymbols !*HashTable !*Files !*File !*File !*File -> (!*PredefinedSymbols, !*HashTable, !*Files, !*File, !*File, !*File, !Optional *FrontEndSyntaxTree)
frontEndInterface upToPhase mod_ident search_paths list_inferred_types predef_symbols hash_table files error io out
# (ok, mod, hash_table, error, predef_symbols, files)
= wantModule cWantIclFile mod_ident NoPos (hash_table -*-> ("Parsing:", mod_ident)) error search_paths predef_symbols files
diff --git a/frontend/main.icl b/frontend/main.icl
index 2b0d7ff..3b9773b 100644
--- a/frontend/main.icl
+++ b/frontend/main.icl
@@ -147,7 +147,7 @@ compileModule mod_name ms
loadModule mod_ident predef_symbols hash_table ms=:{ms_files,ms_error,ms_io,ms_out,ms_paths}
# (predef_symbols, hash_table, ms_files, ms_error, ms_io, ms_out, optional_syntax_tree)
- = frontEndInterface FrontEndPhaseAll mod_ident {sp_locations = [], sp_paths = ms_paths} False predef_symbols hash_table ms_files ms_error ms_io ms_out
+ = frontEndInterface FrontEndPhaseAll mod_ident {sp_locations = [], sp_paths = ms_paths} No predef_symbols hash_table ms_files ms_error ms_io ms_out
ms
= {ms & ms_files=ms_files, ms_error=ms_error,ms_io=ms_io,ms_out=ms_out}
= case optional_syntax_tree of
diff --git a/frontend/syntax.dcl b/frontend/syntax.dcl
index 3f20612..cda1c8c 100644
--- a/frontend/syntax.dcl
+++ b/frontend/syntax.dcl
@@ -808,6 +808,8 @@ cNonRecursiveAppl :== False
:: AttrVarInfo = AVI_Empty | AVI_Attr !TypeAttribute | AVI_Forward !TempAttrId
| AVI_CorrespondenceNumber !Int /* auxiliary used in module comparedefimp */
+ | AVI_Count !Int /* auxiliary used in module typesupport */
+
:: AttrVarInfoPtr :== Ptr AttrVarInfo
:: AttrVarHeap :== Heap AttrVarInfo
@@ -1159,7 +1161,7 @@ instance <<< (Module a) | <<< a, ParsedDefinition, InstanceType, AttributeVar, T
Position, CaseAlt, AType, FunDef, ParsedExpr, TypeAttribute, (Bind a b) | <<< a & <<< b, ParsedConstructor, (TypeDef a) | <<< a, TypeVarInfo,
BasicValue, ATypeVar, TypeRhs, FunctionPattern, (Import from_symbol) | <<< from_symbol, ImportDeclaration, ImportedIdent, CasePatterns,
(Optional a) | <<< a, ConsVariable, BasicType, Annotation, Selection, SelectorDef, ConsDef, LocalDefs, FreeVar, ClassInstance, SignClassification,
- TypeCodeExpression, CoercionPosition
+ TypeCodeExpression, CoercionPosition, AttrInequality
instance == TypeAttribute
instance == Annotation
diff --git a/frontend/syntax.icl b/frontend/syntax.icl
index e695103..8fb217a 100644
--- a/frontend/syntax.icl
+++ b/frontend/syntax.icl
@@ -768,6 +768,8 @@ cNotVarNumber :== -1
:: AttrVarInfo = AVI_Empty | AVI_Attr !TypeAttribute | AVI_Forward !TempAttrId
| AVI_CorrespondenceNumber !Int /* auxiliary used in module comparedefimp */
+ | AVI_Count !Int /* auxiliary used in module typesupport */
+
:: AttrVarInfoPtr :== Ptr AttrVarInfo
:: AttrVarHeap :== Heap AttrVarInfo
@@ -1179,15 +1181,15 @@ where
instance toString TypeAttribute
where
toString (TA_Unique)
- = "* "
+ = "*"
toString (TA_TempVar tav_number)
- = "u" + toString tav_number + ": "
+ = "u" + toString tav_number + ":"
toString (TA_Var avar)
- = toString avar + ": "
+ = toString avar + ":"
toString (TA_RootVar avar)
- = toString avar + ": "
+ = toString avar + ":"
toString (TA_Anonymous)
- = ". "
+ = "."
toString TA_None
= ""
toString TA_Multi
@@ -1808,8 +1810,8 @@ readable :: !Ident -> String // somewhat hacky
readable {id_name}
| id_name=="_cons" || id_name=="_nil"
= "list constructor"
- | id_name % (0,5) == "_tuple"
- = "tuple"
+ | size id_name>0 && id_name.[0]=='_'
+ = id_name%(1, size id_name-1)
= id_name
instance <<< ImportedIdent
diff --git a/frontend/type.dcl b/frontend/type.dcl
index 75390a4..8366dc5 100644
--- a/frontend/type.dcl
+++ b/frontend/type.dcl
@@ -7,5 +7,5 @@ import syntax, check
typeProgram ::!{! Group} !*{# FunDef} !IndexRange !CommonDefs ![Declaration] !{# DclModule} !*Heaps !*PredefinedSymbols !*File
-> (!Bool, !*{# FunDef}, !IndexRange, {! GlobalTCType}, !{# CommonDefs}, !{# {# FunType} }, !*Heaps, !*PredefinedSymbols, !*File)
*/
-typeProgram ::!{! Group} !*{# FunDef} !IndexRange !Bool !CommonDefs ![Declaration] !{# DclModule} !*Heaps !*PredefinedSymbols !*File !*File
+typeProgram ::!{! Group} !*{# FunDef} !IndexRange !(Optional Bool) !CommonDefs ![Declaration] !{# DclModule} !*Heaps !*PredefinedSymbols !*File !*File
-> (!Bool, !*{# FunDef}, !IndexRange, {! GlobalTCType}, !{# CommonDefs}, !{# {# FunType} }, !*Heaps, !*PredefinedSymbols, !*File, !*File)
diff --git a/frontend/type.icl b/frontend/type.icl
index 25ea4a8..333694f 100644
--- a/frontend/type.icl
+++ b/frontend/type.icl
@@ -1561,17 +1561,26 @@ where
attr_partition type_var_env attr_var_env ts.ts_type_heaps ts.ts_var_heap ts.ts_expr_heap ts.ts_error
// MW4..
ts_out = ts.ts_out
- ts_out = case list_inferred_types of
- False
- -> ts_out
- _
- # form = { form_properties = cNoProperties, form_attr_position = No }
- -> ts_out <<< fun_symb <<< " :: "
- <:: (form, clean_fun_type, Yes initialTypeVarBeautifulizer) <<< '\n'
+ th_attrs = ts_type_heaps.th_attrs
+ (ts_out, th_attrs)
+ = case list_inferred_types of
+ No
+ -> (ts_out, th_attrs)
+ Yes show_attributes
+ # form = { form_properties = if show_attributes cAttributed cNoProperties, form_attr_position = No }
+// ts_out = ts_out <<< show_attributes <<< "\n"
+ (printable_type, th_attrs)
+ = case show_attributes of
+ True
+ -> beautifulizeAttributes clean_fun_type th_attrs
+ _
+ -> (clean_fun_type, th_attrs)
+ -> (ts_out <<< fun_symb <<< " :: "
+ <:: (form, printable_type, Yes initialTypeVarBeautifulizer) <<< '\n', th_attrs)
// ..MW4
ts_fun_env = { ts.ts_fun_env & [fun] = CheckedType clean_fun_type }
// MW4 was: -> (type_var_env, attr_var_env, { ts & ts_type_heaps = ts_type_heaps, ts_var_heap = ts_var_heap, ts_expr_heap = ts_expr_heap, ts_fun_env = ts_fun_env, ts_error = ts_error })
- -> (type_var_env, attr_var_env, { ts & ts_type_heaps = ts_type_heaps, ts_var_heap = ts_var_heap, ts_expr_heap = ts_expr_heap, ts_fun_env = ts_fun_env, ts_error = ts_error, ts_out = ts_out })
+ -> (type_var_env, attr_var_env, { ts & ts_type_heaps = { ts_type_heaps & th_attrs = th_attrs }, ts_var_heap = ts_var_heap, ts_expr_heap = ts_expr_heap, ts_fun_env = ts_fun_env, ts_error = ts_error, ts_out = ts_out })
check_function_type fun_type tmp_fun_type=:{tst_lifted} clean_fun_type=:{st_arity, st_args, st_vars, st_attr_vars, st_context} type_ptrs
defs fun_env attr_var_env type_heaps expr_heap error
@@ -1602,7 +1611,7 @@ addLiftedArgumentsToSymbolType st=:{st_arity,st_args,st_vars,st_attr_vars,st_con
}
// MW4 was:typeProgram ::!{! Group} !*{# FunDef} !IndexRange !CommonDefs ![Declaration] !{# DclModule} !*Heaps !*PredefinedSymbols !*File
-typeProgram ::!{! Group} !*{# FunDef} !IndexRange !Bool !CommonDefs ![Declaration] !{# DclModule} !*Heaps !*PredefinedSymbols !*File !*File
+typeProgram ::!{! Group} !*{# FunDef} !IndexRange !(Optional Bool) !CommonDefs ![Declaration] !{# DclModule} !*Heaps !*PredefinedSymbols !*File !*File
// MW4 was: -> (!Bool, !*{# FunDef}, !IndexRange, {! GlobalTCType}, !{# CommonDefs}, !{# {# FunType} }, !*Heaps, !*PredefinedSymbols, !*File)
-> (!Bool, !*{# FunDef}, !IndexRange, {! GlobalTCType}, !{# CommonDefs}, !{# {# FunType} }, !*Heaps, !*PredefinedSymbols, !*File, !*File)
// MW4 was:typeProgram comps fun_defs specials icl_defs imports modules {hp_var_heap, hp_expression_heap, hp_type_heaps} predef_symbols file
diff --git a/frontend/typesupport.dcl b/frontend/typesupport.dcl
index a5d4da3..342dd05 100644
--- a/frontend/typesupport.dcl
+++ b/frontend/typesupport.dcl
@@ -2,7 +2,7 @@ definition module typesupport
import checksupport, StdCompare
-from unitype import Coercions, CoercionTree, AttributePartition
+from unitype import Coercions, CoercionTree, AttributePartition, CT_Empty
// MW: this switch is used to en(dis)able the fusion algorithm
SwitchFusion fuse dont_fuse :== dont_fuse
@@ -47,6 +47,8 @@ expandTypeApplication :: ![ATypeVar] !TypeAttribute !Type ![AType] !TypeAttribut
equivalent :: !SymbolType !TempSymbolType !Int !{# CommonDefs} !*AttributeEnv !*TypeHeaps -> (!Bool, !*AttributeEnv, !*TypeHeaps)
+beautifulizeAttributes :: !SymbolType !*AttrVarHeap -> (!SymbolType, !.AttrVarHeap)
+
:: AttrCoercion =
{ ac_demanded :: !Int
, ac_offered :: !Int
@@ -72,3 +74,34 @@ class substitute a :: !a !*TypeHeaps -> (!a, !*TypeHeaps)
instance substitute AType, Type, TypeContext, AttrInequality, CaseType, [a] | substitute a
instance <<< TempSymbolType
+
+removeInequality :: !Int !Int !*Coercions -> .Coercions
+anonymizeAttrVars :: !SymbolType !*AttrVarHeap -> (!SymbolType, !.AttrVarHeap)
+flattenCoercionTree :: !u:CoercionTree -> (![Int], !u:CoercionTree)
+assignNumbersToAttrVars :: !SymbolType !*AttrVarHeap -> (!Int, ![AttributeVar], !.AttrVarHeap)
+getImplicitAttrInequalities :: !SymbolType -> [AttrInequality]
+ // retrieve those inequalities that are implied by propagation
+emptyCoercions :: !Int -> .Coercions
+ // Int: nr of attribute variables
+addAttrEnvInequalities :: ![AttrInequality] !*Coercions !u:AttrVarHeap
+ -> (!.Coercions, !u:AttrVarHeap)
+ // assertion: the attribute variables point to (AVI_Attr (TA_TempVar nr)) where
+ // nr corresponds to the attribute variable
+
+//accCoercionTree :: !.(u:CoercionTree -> (.a,u:CoercionTree)) !Int !*{!u:CoercionTree} -> (!.a,!{!u:CoercionTree})
+accCoercionTree f i coercion_trees
+ :== acc_coercion_tree i coercion_trees
+ where
+ acc_coercion_tree i coercion_trees
+ # (coercion_tree, coercion_trees) = replace coercion_trees i CT_Empty
+ (x, coercion_tree) = f coercion_tree
+ = (x, snd (replace coercion_trees i coercion_tree))
+
+//accCoercionTree :: !.(u:CoercionTree -> u:CoercionTree) !Int !*{!u:CoercionTree} -> {!u:CoercionTree}
+appCoercionTree f i coercion_trees
+ :== acc_coercion_tree i coercion_trees
+ where
+ acc_coercion_tree i coercion_trees
+ # (coercion_tree, coercion_trees) = replace coercion_trees i CT_Empty
+ = snd (replace coercion_trees i (f coercion_tree))
+
diff --git a/frontend/typesupport.icl b/frontend/typesupport.icl
index 5cf3781..700fbc3 100644
--- a/frontend/typesupport.icl
+++ b/frontend/typesupport.icl
@@ -1,7 +1,7 @@
implementation module typesupport
import StdEnv, StdCompare
-import syntax, parse, check, unitype, utilities, checktypes // , RWSDebug
+import syntax, parse, check, unitype, utilities, checktypes, RWSDebug
// MW: this switch is used to en(dis)able the fusion algorithm
SwitchFusion fuse dont_fuse :== dont_fuse
@@ -827,6 +827,7 @@ cMarkAttribute :== 4
cBrackets :== 8
cCommaSeparator :== 16
cArrowSeparator :== 32
+cAndSeparator :== 64
checkProperty form property :== not (form.form_properties bitand property == 0)
setProperty form property :== {form & form_properties = form.form_properties bitor property}
@@ -839,6 +840,11 @@ clearProperty form property :== {form & form_properties = form.form_properties b
class writeType a :: !*File !(Optional TypeVarBeautifulizer) (!Format, !a) -> (!*File, !Optional TypeVarBeautifulizer)
+instance writeType AttributeVar
+where
+ writeType file opt_beautifulizer (form, av)
+ = (file <<< av, opt_beautifulizer)
+
instance writeType SymbolType
where
writeType file opt_beautifulizer (form, {st_args, st_arity, st_result, st_context, st_attr_env})
@@ -858,13 +864,32 @@ where
False
# (file, opt_beautifulizer)
= writeType (file <<< ", [") opt_beautifulizer
- (setProperty form cCommaSeparator, st_attr_env)
+ (setProperty form cCommaSeparator, grouped (hd st_attr_env).ai_demanded [] st_attr_env)
-> (file <<< ']', opt_beautifulizer)
where
show_context form [] file_opt_beautifulizer
= file_opt_beautifulizer
show_context form contexts (file, opt_beautifulizer)
- = writeType (file <<< " | ") opt_beautifulizer (setProperty form cCommaSeparator, contexts)
+ = writeType (file <<< " | ") opt_beautifulizer (setProperty form cAndSeparator, contexts)
+ // grouped takes care that inequalityies like [a<=c, b<=c] are printed like [a b <= c]
+ grouped group_var accu []
+ = [{ ig_offered = accu, ig_demanded = group_var}]
+ grouped group_var accu [{ai_offered, ai_demanded}:ineqs]
+ | group_var==ai_demanded
+ = grouped group_var [ai_offered:accu] ineqs
+ =[{ ig_offered = accu, ig_demanded = group_var}: grouped ai_demanded [ai_offered] ineqs]
+
+:: InequalityGroup =
+ { ig_offered :: ![AttributeVar]
+ , ig_demanded :: !AttributeVar
+ }
+
+instance writeType InequalityGroup
+where
+ writeType file opt_beautifulizer (form, {ig_offered,ig_demanded})
+ # (file, opt_beautifulizer)
+ = writeType file opt_beautifulizer (form, ig_offered)
+ = writeType (file <<< " <= ") opt_beautifulizer (form, ig_demanded)
instance writeType TypeContext
where
@@ -935,6 +960,8 @@ where
= writeWithinBrackets "{#" "}" file opt_beautifulizer (setProperty form cCommaSeparator, types)
| is_tuple type_name type_arity
= writeWithinBrackets "(" ")" file opt_beautifulizer (setProperty form cCommaSeparator, types)
+ | is_string_type type_name
+ = (file <<< "String", opt_beautifulizer)
| type_arity == 0
= (file <<< type_name, opt_beautifulizer)
| checkProperty form cBrackets
@@ -957,6 +984,7 @@ where
is_lazy_array {id_name} = id_name == "_array"
is_strict_array {id_name} = id_name == "_!array"
is_unboxed_array {id_name} = id_name == "_#array"
+ is_string_type {id_name} = id_name == "_string"
// MW4 was: writeType file (form, arg_type --> res_type)
writeType file opt_beautifulizer (form, arg_type --> res_type)
@@ -997,11 +1025,12 @@ writeWithinBrackets br_open br_close file opt_beautifulizer (form, types)
writeBeautifulTypeVar file beautifulizer=:{tvb_visited_typevars, tvb_fresh_vars} type_variable
| sanity_check_failed type_variable
= abort "bug nr 12345 in module typesupport"
- = case assoc_list_lookup type_variable tvb_visited_typevars of
+ # type_var_ptr = toTypeVarPtr type_variable
+ = case assoc_list_lookup type_var_ptr tvb_visited_typevars of
No
-> (file <<< hd tvb_fresh_vars,
Yes { beautifulizer &
- tvb_visited_typevars = [(type_variable, hd tvb_fresh_vars):tvb_visited_typevars],
+ tvb_visited_typevars = [(type_var_ptr, hd tvb_fresh_vars):tvb_visited_typevars],
tvb_fresh_vars = tl tvb_fresh_vars })
Yes (_, beautiful_var_name)
-> (file <<< beautiful_var_name, Yes beautifulizer)
@@ -1019,17 +1048,24 @@ instance writeType ConsVariable where
= (file <<< cons_variable, No)
writeType file yes_beautifulizer (_, cv=:(TempQCV _))
= (file <<< cv, yes_beautifulizer)
- writeType file yes_beautifulizer=:(Yes beautifulizer=:{tvb_visited_consvars, tvb_fresh_vars})
+ writeType file yes_beautifulizer=:(Yes beautifulizer=:{tvb_visited_typevars, tvb_fresh_vars})
(_, cons_variable)
- = case assoc_list_lookup cons_variable tvb_visited_consvars of
+ # cons_var_ptr = toTypeVarPtrCV cons_variable
+ = case assoc_list_lookup cons_var_ptr tvb_visited_typevars of
No
-> (file <<< hd tvb_fresh_vars,
Yes { beautifulizer &
- tvb_visited_consvars = [(cons_variable, hd tvb_fresh_vars):tvb_visited_consvars],
+ tvb_visited_typevars = [(cons_var_ptr, hd tvb_fresh_vars):tvb_visited_typevars],
tvb_fresh_vars = tl tvb_fresh_vars })
Yes (_, beautiful_var_name)
-> (file <<< beautiful_var_name, yes_beautifulizer)
+toTypeVarPtrCV (CV {tv_info_ptr}) = tv_info_ptr
+
+toTypeVarPtr (TV {tv_info_ptr}) = tv_info_ptr
+toTypeVarPtr (GTV {tv_info_ptr}) = tv_info_ptr
+toTypeVarPtr (TQV {tv_info_ptr}) = tv_info_ptr
+
assoc_list_lookup _ [] = No
assoc_list_lookup t1 [hd=:(t2, _):tl]
| t1==t2
@@ -1049,12 +1085,15 @@ where
= show_elem elem_number (clearProperty form cCommaSeparator) type file_opt_beautifulizer
| checkProperty form cArrowSeparator
= show_elem elem_number (clearProperty form cArrowSeparator) type file_opt_beautifulizer
+ | checkProperty form cAndSeparator
+ = show_elem elem_number (clearProperty form cAndSeparator) type file_opt_beautifulizer
= show_elem elem_number (setProperty form cBrackets) type file_opt_beautifulizer
show_list elem_number form [type : types] file_opt_beautifulizer
# (elem_format, seperator)
= if (checkProperty form cCommaSeparator) (clearProperty form cCommaSeparator, ",")
(if (checkProperty form cArrowSeparator) (clearProperty form cArrowSeparator, " -> ")
- (setProperty form cBrackets, " "))
+ (if (checkProperty form cAndSeparator) (clearProperty form cAndSeparator, " & ")
+ (setProperty form cBrackets, " ")))
(file, opt_beautifulizer)
= show_elem elem_number elem_format type file_opt_beautifulizer
= show_list (inc elem_number) form types (file <<< seperator, opt_beautifulizer)
@@ -1096,19 +1135,321 @@ where
// MW4..
:: TypeVarBeautifulizer =
- { tvb_visited_typevars :: ![(Type, String)]
- , tvb_visited_consvars :: ![(ConsVariable, String)]
- // tvb_visited_typevars and tvb_visited_consvars associate type (constructor) variables with
- // strings, the type in tvb_visited_typevars should be only GTV, TV, TempV, TQV, TempQV, TLifted.
- // (associations lists are slow but cool)
+ { tvb_visited_typevars :: ![(TypeVarInfoPtr, String)]
, tvb_fresh_vars :: ![String]
}
initialTypeVarBeautifulizer :: TypeVarBeautifulizer
initialTypeVarBeautifulizer
- = { tvb_visited_typevars = [], tvb_visited_consvars = [], tvb_fresh_vars = fresh_vars 'a' (-1) }
+ = { tvb_visited_typevars = [], tvb_fresh_vars = fresh_vars 'a' (-1) }
where
fresh_vars 'i' i
= fresh_vars 'a' (i+1)
fresh_vars ch i
= [if (i==(-1)) (toString ch) (toString ch+++toString i): fresh_vars (inc ch) i]
+
+getImplicitAttrInequalities :: !SymbolType -> [AttrInequality]
+ // retrieve those inequalities that are implied by propagation
+getImplicitAttrInequalities st=:{st_args, st_result}
+ # ineqs1 = get_ineqs_of_atype_list st_args
+ ineqs2 = get_ineqs_of_atype st_result
+ = uniqueBagToList (Pair ineqs1 ineqs2)
+ where
+ get_ineqs_of_atype :: !AType -> !.Bag AttrInequality
+ get_ineqs_of_atype a_type=:{at_attribute=TA_Var outer_av, at_type=at_type=:TA type_symb_ident type_args}
+ # ({tsp_propagation}) = type_symb_ident.type_prop
+ implicit_ineqs_1 = get_superflous_ineqs outer_av type_args tsp_propagation
+ | isEmptyBag implicit_ineqs_1
+ = get_ineqs_of_type at_type
+ # implicit_ineqs_2 = get_ineqs_of_type at_type
+ = Pair implicit_ineqs_1 implicit_ineqs_2
+ where
+ get_superflous_ineqs :: !AttributeVar ![AType] !PropClassification -> .Bag AttrInequality
+ get_superflous_ineqs outer_av [] tsp_propagation
+ = Empty
+ get_superflous_ineqs outer_av [{at_attribute}:type_args] tsp_propagation
+ # other_ineqs = get_superflous_ineqs outer_av type_args (tsp_propagation>>1)
+ | tsp_propagation bitand 1==0
+ // the type doesn't propagate in this argument
+ = other_ineqs
+ = case at_attribute of
+ TA_Var inner_av
+ -> Pair (Single {ai_demanded=inner_av, ai_offered=outer_av}) other_ineqs
+ _ -> other_ineqs
+ get_ineqs_of_atype {at_type}
+ = get_ineqs_of_type at_type
+
+ get_ineqs_of_type (TA ts args)
+ = get_ineqs_of_atype_list args
+ get_ineqs_of_type (l --> r)
+ = Pair (get_ineqs_of_atype l) (get_ineqs_of_atype r)
+ get_ineqs_of_type (cv :@: args)
+ = get_ineqs_of_atype_list args
+ get_ineqs_of_type _
+ = Empty
+
+ get_ineqs_of_atype_list []
+ = Empty
+ get_ineqs_of_atype_list [a_type:a_types]
+ = Pair (get_ineqs_of_atype a_type) (get_ineqs_of_atype_list a_types)
+
+beautifulizeAttributes :: !SymbolType !*AttrVarHeap -> (!SymbolType, !.AttrVarHeap)
+beautifulizeAttributes symbol_type th_attrs
+ # (nr_of_attr_vars, all_attr_vars, th_attrs)
+ = assignNumbersToAttrVars symbol_type th_attrs
+ (attr_env_coercions, th_attrs)
+ = addAttrEnvInequalities symbol_type.st_attr_env (emptyCoercions nr_of_attr_vars) th_attrs
+ (all_int_inequalities, th_attrs)
+ = mapSt pointers_to_int symbol_type.st_attr_env th_attrs
+ (_, attr_env_coercions)
+ = foldSt removeRedundancy all_int_inequalities
+ (createArray nr_of_attr_vars False, attr_env_coercions)
+ implicit_inequalities
+ = getImplicitAttrInequalities symbol_type
+ (implicit_int_inequalities, th_attrs)
+ = mapSt pointers_to_int implicit_inequalities th_attrs
+ attr_env_coercions
+ = foldSt remove_inequality implicit_int_inequalities attr_env_coercions
+ st_attr_env
+ = coercionsToAttrEnv {el \\ el<-all_attr_vars } attr_env_coercions
+ (symbol_type, th_attrs)
+ = anonymizeAttrVars { symbol_type & st_attr_env = st_attr_env } th_attrs
+ = (symbol_type, th_attrs)
+ where
+ pointers_to_int {ai_offered, ai_demanded} th_attrs
+ # (AVI_Attr (TA_TempVar offered), th_attrs) = readPtr ai_offered.av_info_ptr th_attrs
+ (AVI_Attr (TA_TempVar demanded), th_attrs) = readPtr ai_demanded.av_info_ptr th_attrs
+ = ({ ac_offered = offered, ac_demanded = demanded }, th_attrs)
+ remove_inequality {ac_offered, ac_demanded} attr_env_coercions
+ = removeInequality ac_offered ac_demanded attr_env_coercions
+
+ coercionsToAttrEnv :: !{AttributeVar} !Coercions -> [AttrInequality]
+ coercionsToAttrEnv attr_vars {coer_offered}
+ = flatten [ [ {ai_offered = attr_vars.[offered], ai_demanded = attr_vars.[demanded] }
+ \\ offered <- fst (flattenCoercionTree offered_tree) ]
+ \\ offered_tree<-:coer_offered & demanded<-[0..] ]
+
+
+ removeRedundancy :: !AttrCoercion !(!*{#Bool}, !*Coercions) -> (!.{#Bool}, !.Coercions)
+ removeRedundancy {ac_offered, ac_demanded} (visited, attr_env_coercions=:{coer_demanded})
+ // all i:not visited.[i]
+ # (descendants, coer_demanded)
+ = accCoercionTree flattenCoercionTree ac_offered coer_demanded
+ (path_exists, (visited, coer_demanded))
+ = searchPath (removeMember ac_demanded descendants) ac_demanded (visited, coer_demanded)
+ #! size
+ = size visited
+ # visited
+ = { visited & [i] = False \\ i<-[0..size-1] }
+ attr_env_coercions
+ = { attr_env_coercions & coer_demanded = coer_demanded }
+ | path_exists
+ // the inequality was redundant (like the first one in [a<=c, a<=b, b<=c]
+ = (visited, removeInequality ac_offered ac_demanded attr_env_coercions)
+ = (visited, attr_env_coercions)
+ where
+ searchPath :: ![Int] Int !(!*{#Bool}, !{!*CoercionTree}) -> (!Bool, (!.{#Bool}, !{!.CoercionTree}))
+ searchPath [] _ visited_coer_demanded
+ = (False, visited_coer_demanded)
+ searchPath [x:xs] goal (visited, coer_demanded)
+ // not visited.[x]
+ | x==goal
+ = (True, (visited, coer_demanded))
+ # visited
+ = { visited & [x] = True }
+ (descendants, coer_demanded)
+ = accCoercionTree flattenCoercionTree x coer_demanded
+ (xs, visited)
+ = foldSt add_unvisited_node descendants (xs, visited)
+ = searchPath xs goal (visited, coer_demanded)
+
+ add_unvisited_node :: !Int !(![Int], !u:{#Bool}) -> !(![Int], !u:{#Bool})
+ add_unvisited_node candidate (accu, visited)
+ | visited.[candidate]
+ = (accu, visited)
+ = ([candidate:accu], visited)
+
+assignNumbersToAttrVars :: !SymbolType !*AttrVarHeap -> (!Int, ![AttributeVar], !.AttrVarHeap)
+assignNumbersToAttrVars {st_attr_vars, st_args, st_result, st_attr_env} th_attrs
+ # th_attrs
+ = foldSt initialise_to_AVI_Empty st_attr_vars th_attrs
+ (next_number, numbered_vars_accu, th_attrs)
+ = foldSt assign_numbers_attr_ineq st_attr_env
+ (assign_numbers_atype st_result
+ (foldSt assign_numbers_atype st_args (0, [], th_attrs)))
+ = (next_number, reverse numbered_vars_accu, th_attrs)
+ where
+ assign_numbers_atype atype=:{at_attribute=TA_Var av=:{av_info_ptr}, at_type}
+ (next_number, numbered_vars_accu, th_attrs)
+ # (avi, th_attrs) = readPtr av_info_ptr th_attrs
+ = assign_numbers_type at_type
+ (assign_number avi av (next_number, numbered_vars_accu, th_attrs))
+ assign_numbers_atype atype=:{at_type} assign_state
+ = assign_numbers_type at_type assign_state
+
+ assign_numbers_type (TA _ args) assign_state
+ = foldSt assign_numbers_atype args assign_state
+ assign_numbers_type (l --> r) assign_state
+ = assign_numbers_atype l (assign_numbers_atype r assign_state)
+ assign_numbers_type (_ :@: args) assign_state
+ = foldSt assign_numbers_atype args assign_state
+ assign_numbers_type _ assign_state
+ = assign_state
+
+ assign_numbers_attr_ineq {ai_offered, ai_demanded} (next_number, numbered_vars_accu, th_attrs)
+ # (avi_offered, th_attrs) = readPtr ai_offered.av_info_ptr th_attrs
+ (avi_demanded, th_attrs) = readPtr ai_demanded.av_info_ptr th_attrs
+ = assign_number avi_offered ai_offered
+ (assign_number avi_demanded ai_demanded (next_number, numbered_vars_accu, th_attrs))
+
+ assign_number AVI_Empty av=:{av_info_ptr} (next_number, numbered_vars_accu, th_attrs)
+ = (next_number+1, [av:numbered_vars_accu],
+ writePtr av_info_ptr (AVI_Attr (TA_TempVar next_number)) th_attrs)
+ assign_number _ _ assign_state
+ = assign_state
+
+//accCoercionTree :: !.(u:CoercionTree -> (.a,u:CoercionTree)) !Int !*{!u:CoercionTree} -> (!.a,!{!u:CoercionTree})
+accCoercionTree f i coercion_trees
+ :== acc_coercion_tree i coercion_trees
+ where
+ acc_coercion_tree i coercion_trees
+ # (coercion_tree, coercion_trees) = replace coercion_trees i CT_Empty
+ (x, coercion_tree) = f coercion_tree
+ = (x, snd (replace coercion_trees i coercion_tree))
+
+appCoercionTree f i coercion_trees
+ :== acc_coercion_tree i coercion_trees
+ where
+ acc_coercion_tree i coercion_trees
+ # (coercion_tree, coercion_trees) = replace coercion_trees i CT_Empty
+ = snd (replace coercion_trees i (f coercion_tree))
+
+flattenCoercionTree :: !u:CoercionTree -> (![Int], !u:CoercionTree)
+flattenCoercionTree tree
+ = flatten_ct ([], tree)
+ where
+ flatten_ct (accu, CT_Empty)
+ = (accu, CT_Empty)
+ flatten_ct (accu, CT_Node i left right)
+ # (accu, right) = flatten_ct (accu, right)
+ (accu, left) = flatten_ct ([i:accu], left)
+ = (accu, CT_Node i left right)
+
+anonymizeAttrVars :: !SymbolType !*AttrVarHeap -> (!SymbolType, !.AttrVarHeap)
+anonymizeAttrVars st=:{st_attr_vars, st_args, st_result, st_attr_env} th_attrs
+ # th_attrs
+ = countAttrVars st th_attrs
+ th_attrs
+ = foldSt markUsedAttrVars st_attr_env th_attrs
+ (st_args, th_attrs) = mapSt anonymize_atype st_args th_attrs
+ (st_result, th_attrs) = anonymize_atype st_result th_attrs
+ = ({ st & st_args = st_args, st_result = st_result }, th_attrs)
+ where
+ anonymize_atype atype=:{at_attribute=TA_Var {av_info_ptr}, at_type} th_attrs
+ # (at_type, th_attrs) = anonymize_type at_type th_attrs
+ (avi, th_attrs) = readPtr av_info_ptr th_attrs
+ = case avi of
+ AVI_Count c
+ // this attribute variable doesn't occur in the attribute inequalities
+ | isTypeVar at_type || c==1
+ // number of occurences doesn't matter for type variables
+ -> ({ atype & at_type = at_type, at_attribute = TA_Anonymous }, th_attrs)
+ -> ({ atype & at_type = at_type }, th_attrs)
+ _
+ -> ({ atype & at_type = at_type }, th_attrs)
+ where
+ isTypeVar (TV _) = True
+ isTypeVar (GTV _) = True
+ isTypeVar (TQV _) = True
+ isTypeVar _ = False
+ anonymize_atype atype=:{at_type} th_attrs
+ # (at_type, th_attrs) = anonymize_type at_type th_attrs
+ = ({ atype & at_type = at_type }, th_attrs)
+
+ anonymize_type (TA tsi args) th_attrs
+ # (args, th_attrs) = mapSt anonymize_atype args th_attrs
+ = (TA tsi args, th_attrs)
+ anonymize_type (l --> r) th_attrs
+ # (l, th_attrs) = anonymize_atype l th_attrs
+ (r, th_attrs) = anonymize_atype r th_attrs
+ = (l --> r, th_attrs)
+ anonymize_type (cv :@: args) th_attrs
+ # (args, th_attrs) = mapSt anonymize_atype args th_attrs
+ = (cv :@: args, th_attrs)
+ anonymize_type x th_attrs
+ = (x, th_attrs)
+
+ countAttrVars :: !SymbolType !*AttrVarHeap -> .AttrVarHeap
+ // for all attribute variables: set the attrVarInfo to (AVI_count c) where c is the number of
+ // occurences in of that attribute variable in the SymbolType (excluding inequalities)
+ countAttrVars {st_attr_vars, st_args, st_result} th_attrs
+ # th_attrs
+ = foldSt (\av=:{av_info_ptr} th_attrs -> writePtr av_info_ptr (AVI_Count 0) th_attrs)
+ st_attr_vars th_attrs
+ = foldSt count_attr_vars_of_atype st_args (count_attr_vars_of_atype st_result th_attrs)
+ where
+ count_attr_vars_of_atype {at_attribute=TA_Var {av_info_ptr}, at_type} th_attrs
+ # (AVI_Count c, th_attrs) = readPtr av_info_ptr th_attrs
+ = count_attr_vars_of_type at_type (writePtr av_info_ptr (AVI_Count (c+1)) th_attrs)
+ count_attr_vars_of_atype {at_type} th_attrs
+ = count_attr_vars_of_type at_type th_attrs
+
+ count_attr_vars_of_type (TA _ args) th_attrs
+ = foldSt count_attr_vars_of_atype args th_attrs
+ count_attr_vars_of_type (l --> r) th_attrs
+ = count_attr_vars_of_atype l (count_attr_vars_of_atype r th_attrs)
+ count_attr_vars_of_type (_ :@: args) th_attrs
+ = foldSt count_attr_vars_of_atype args th_attrs
+ count_attr_vars_of_type _ th_attrs
+ = th_attrs
+
+
+initialise_to_AVI_Empty {av_info_ptr} th_attrs
+ = writePtr av_info_ptr AVI_Empty th_attrs
+
+markUsedAttrVars {ai_offered, ai_demanded} th_attrs
+ = writePtr ai_offered.av_info_ptr (AVI_Forward 0)
+ (writePtr ai_demanded.av_info_ptr (AVI_Forward 0) th_attrs)
+ // misuse AVI_Forward to indicate that this attribute variable is referenced in
+ // the attribute inequalities
+
+removeInequality :: !Int !Int !*Coercions -> .Coercions
+removeInequality offered demanded attr_env_coercions=:{coer_offered, coer_demanded}
+ # coer_offered = appCoercionTree (removeNode offered) demanded coer_offered
+ coer_demanded = appCoercionTree (removeNode demanded) offered coer_demanded
+ = { attr_env_coercions & coer_demanded = coer_demanded, coer_offered = coer_offered }
+ where
+ removeNode :: !Int !*CoercionTree -> !.CoercionTree
+ removeNode i1 (CT_Node i2 left right)
+ | i1<i2
+ = CT_Node i2 (removeNode i1 left) right
+ | i1>i2
+ = CT_Node i2 left (removeNode i1 right)
+ = rightInsert left right
+ removeNode i1 CT_Empty
+ = CT_Empty
+
+ rightInsert :: !*CoercionTree !*CoercionTree -> !.CoercionTree
+ rightInsert CT_Empty right
+ = right
+ rightInsert (CT_Node i left right2) right1
+ = CT_Node i left (rightInsert right2 right1)
+
+
+emptyCoercions :: !Int -> .Coercions
+emptyCoercions nr_of_attr_vars
+ = { coer_demanded = create_a_unique_array nr_of_attr_vars,
+ coer_offered = create_a_unique_array nr_of_attr_vars }
+ where
+ create_a_unique_array :: !Int -> .{!.CoercionTree}
+ create_a_unique_array n
+ = { CT_Empty \\ i <- [1..n] }
+
+addAttrEnvInequalities :: ![AttrInequality] !*Coercions !u:AttrVarHeap -> (!.Coercions, !u:AttrVarHeap)
+addAttrEnvInequalities st_attr_env coercions th_attrs
+ = foldSt add_attr_env_inequality st_attr_env (coercions, th_attrs)
+ where
+ add_attr_env_inequality {ai_offered, ai_demanded} (coercions, th_attrs)
+ # (AVI_Attr (TA_TempVar offered), th_attrs) = readPtr ai_offered.av_info_ptr th_attrs
+ (AVI_Attr (TA_TempVar demanded), th_attrs) = readPtr ai_demanded.av_info_ptr th_attrs
+ = (newInequality offered demanded coercions, th_attrs)