From bb3fe3aae2a3a8fb53b4deecd102f4766289ae50 Mon Sep 17 00:00:00 2001
From: Graham Nelson
subkind of W is replaced by W.
We do need to be careful over contravariance: the kind "object based rulebook +producing a number" is stronger than "thing based rulebook producing a number", +not weaker, because the K term for "K based rulebook producing L" is contravariant. +
+kind *Kinds::weaken(kind *K, kind *W) { if (Kinds::is_proper_constructor(K)) { @@ -508,13 +513,19 @@int a = Kinds::arity_of_constructor(K); if (a == 1) { X = Kinds::unary_construction_material(K); - return Kinds::unary_con(K->construct, Kinds::weaken(X, W)); + kind *WX = X; + if (KindConstructors::variance(K->construct, 0) == COVARIANT) WX = Kinds::weaken(X, W); + return Kinds::unary_con(K->construct, WX); } else { Kinds::binary_construction_material(K, &X, &Y); - return Kinds::binary_con(K->construct, Kinds::weaken(X, W), Kinds::weaken(Y, W)); + kind *WX = X, *WY = Y; + if (KindConstructors::variance(K->construct, 0) == COVARIANT) WX = Kinds::weaken(X, W); + if (KindConstructors::variance(K->construct, 1) == COVARIANT) WY = Kinds::weaken(Y, W); + return Kinds::binary_con(K->construct, WX, WY); } } else { - if ((K) && (Kinds::conforms_to(K, W)) && (Kinds::eq(K, K_nil) == FALSE) && (Kinds::eq(K, K_void) == FALSE)) return W; + if ((K) && (Kinds::conforms_to(K, W)) && (Kinds::eq(K, K_nil) == FALSE) && + (Kinds::eq(K, K_void) == FALSE)) return W; } return K; } diff --git a/docs/kinds-module/4-kc2.html b/docs/kinds-module/4-kc2.html index d82987fe64..e2fd3ad91b 100644 --- a/docs/kinds-module/4-kc2.html +++ b/docs/kinds-module/4-kc2.html @@ -571,7 +571,7 @@
return con->tupling[b]; } -int KindConstructors::variance(kind_constructor *con, int b) { +int KindConstructors::variance(kind_constructor *con, int b) { return con->variance[b]; } diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt index d396ad0e5e..1a95f393ae 100644 --- a/inform7/Figures/timings-diagnostics.txt +++ b/inform7/Figures/timings-diagnostics.txt @@ -1,10 +1,10 @@ 100.0% in inform7 run - 66.4% in compilation to Inter - 43.9% in //Sequence::undertake_queued_tasks// - 4.1% in //MajorNodes::pre_pass// - 3.4% in //MajorNodes::pass_1// + 65.7% in compilation to Inter + 43.3% in //Sequence::undertake_queued_tasks// + 4.4% in //MajorNodes::pre_pass// + 3.3% in //MajorNodes::pass_1// 2.0% in //RTKindConstructors::compile// - 1.7% in //ImperativeDefinitions::assess_all// + 1.6% in //ImperativeDefinitions::assess_all// 1.3% in //RTPhrasebook::compile_entries// 1.0% in //Sequence::lint_inter// 0.6% in //ImperativeDefinitions::compile_first_block// @@ -15,16 +15,17 @@ 0.3% in //Sequence::undertake_queued_tasks// 0.3% in //Sequence::undertake_queued_tasks// 0.3% in //Task::make_built_in_kind_constructors// - 4.9% not specifically accounted for - 26.2% in running Inter pipeline - 8.6% in step 14/15: generate inform6 -> auto.inf - 6.9% in step 5/15: load-binary-kits - 5.5% in step 6/15: make-synoptic-module + 4.7% not specifically accounted for + 27.1% in running Inter pipeline + 8.8% in step 14/15: generate inform6 -> auto.inf + 6.7% in step 5/15: load-binary-kits + 5.7% in step 6/15: make-synoptic-module 2.0% in step 9/15: make-identifiers-unique + 0.3% in step 11/15: eliminate-redundant-labels 0.3% in step 12/15: eliminate-redundant-operations 0.3% in step 4/15: compile-splats 0.3% in step 7/15: shorten-wiring 0.3% in step 8/15: detect-indirect-calls - 1.7% not specifically accounted for - 6.2% in supervisor - 1.1% not specifically accounted for + 2.1% not specifically accounted for + 6.4% in supervisor + 0.7% not specifically accounted for diff --git a/services/kinds-module/Chapter 2/Kinds.w b/services/kinds-module/Chapter 2/Kinds.w index 38cf4abf0c..bf34d2d2c6 100644 --- a/services/kinds-module/Chapter 2/Kinds.w +++ b/services/kinds-module/Chapter 2/Kinds.w @@ -380,6 +380,10 @@ kind *Kinds::substitute_inner(kind *K, kind **meanings, int *changed, int contra This operation corresponds to rounding kinds up to |W|: that is, any subkind of |W| is replaced by |W|. +We do need to be careful over contravariance: the kind "object based rulebook +producing a number" is stronger than "thing based rulebook producing a number", +not weaker, because the K term for "K based rulebook producing L" is contravariant. + = kind *Kinds::weaken(kind *K, kind *W) { if (Kinds::is_proper_constructor(K)) { @@ -387,13 +391,19 @@ kind *Kinds::weaken(kind *K, kind *W) { int a = Kinds::arity_of_constructor(K); if (a == 1) { X = Kinds::unary_construction_material(K); - return Kinds::unary_con(K->construct, Kinds::weaken(X, W)); + kind *WX = X; + if (KindConstructors::variance(K->construct, 0) == COVARIANT) WX = Kinds::weaken(X, W); + return Kinds::unary_con(K->construct, WX); } else { Kinds::binary_construction_material(K, &X, &Y); - return Kinds::binary_con(K->construct, Kinds::weaken(X, W), Kinds::weaken(Y, W)); + kind *WX = X, *WY = Y; + if (KindConstructors::variance(K->construct, 0) == COVARIANT) WX = Kinds::weaken(X, W); + if (KindConstructors::variance(K->construct, 1) == COVARIANT) WY = Kinds::weaken(Y, W); + return Kinds::binary_con(K->construct, WX, WY); } } else { - if ((K) && (Kinds::conforms_to(K, W)) && (Kinds::eq(K, K_nil) == FALSE) && (Kinds::eq(K, K_void) == FALSE)) return W; + if ((K) && (Kinds::conforms_to(K, W)) && (Kinds::eq(K, K_nil) == FALSE) && + (Kinds::eq(K, K_void) == FALSE)) return W; } return K; }