public void MergeInplace_TwoPrimitives_Throws() { var a = CreateNode("a", StatePrimitive.I16); var b = CreateNode("b", StatePrimitive.I32); Assert.Catch(() => SolvingFunctions.MergeInplace(a, b)); }
public void GetMergedStateOrNull_ConstrainsAndPrimitiveThatFit() { var res = SolvingFunctions.GetMergedStateOrNull(StatePrimitive.I64, new ConstrainsState(StatePrimitive.I16, StatePrimitive.Real)); Assert.AreEqual(res, StatePrimitive.I64); }
public bool Apply(ICompositeState ancestor, ICompositeState descendant, TicNode ancestorNode, TicNode descendantNode) { if (ancestor.GetType() != descendant.GetType()) { return(false); } if (ancestor is StateArray ancArray) { var descArray = (StateArray)descendant; SolvingFunctions.PushConstraints(descArray.ElementNode, ancArray.ElementNode); return(true); } if (ancestor is StateFun ancFun) { var descFun = (StateFun)descendant; if (descFun.ArgsCount != ancFun.ArgsCount) { return(false); } PushFunTypeArgumentsConstraints(descFun, ancFun); return(true); } if (ancestor is StateStruct ancStruct) { return(TryMergeStructFields(ancStruct, (StateStruct)descendant)); } return(false); }
void AssertGetMergedStateThrows(IState stateA, IState stateB) { Assert.Throws <InvalidOperationException>( () => SolvingFunctions.GetMergedState(stateA, stateB)); Assert.Throws <InvalidOperationException>( () => SolvingFunctions.GetMergedState(stateB, stateA)); }
public void GetMergedStateOrNull_EmptyAndNonEmptyStruct() { var nonEmpty = new StateStruct( new Dictionary <string, TicNode> { { "i", TicNode.CreateTypeVariableNode(StatePrimitive.I32) }, { "r", TicNode.CreateTypeVariableNode(StatePrimitive.Real) } } ); var res = SolvingFunctions.GetMergedStateOrNull( nonEmpty, new StateStruct()); var expected = new StateStruct( new Dictionary <string, TicNode> { { "i", TicNode.CreateTypeVariableNode(StatePrimitive.I32) }, { "r", TicNode.CreateTypeVariableNode(StatePrimitive.Real) } }); Assert.AreEqual(res, expected); var invertedres = SolvingFunctions.GetMergedStateOrNull( new StateStruct(), nonEmpty); Assert.AreEqual(res, invertedres); }
public void GetMergedStateOrNull_TwoConcreteStructsWithDifferentFields() { var res = SolvingFunctions.GetMergedStateOrNull( new StateStruct( new Dictionary <string, TicNode> { { "i", TicNode.CreateTypeVariableNode(StatePrimitive.I32) }, { "r", TicNode.CreateTypeVariableNode(StatePrimitive.Real) } } ), new StateStruct( new Dictionary <string, TicNode> { { "r", TicNode.CreateTypeVariableNode(StatePrimitive.Real) }, { "b", TicNode.CreateTypeVariableNode(StatePrimitive.Bool) } })); var expected = new StateStruct( new Dictionary <string, TicNode> { { "i", TicNode.CreateTypeVariableNode(StatePrimitive.I32) }, { "r", TicNode.CreateTypeVariableNode(StatePrimitive.Real) }, { "b", TicNode.CreateTypeVariableNode(StatePrimitive.Bool) } }); Assert.AreEqual(res, expected); }
public void GetMergedStateOrNull_TwoNonEmpty() { var res = SolvingFunctions.GetMergedStateOrNull( new StateStruct(), new StateStruct()); Assert.AreEqual(res, new StateStruct()); }
public void GetMergedStateOrNull_TwoSameConcreteStructs() { var res = SolvingFunctions.GetMergedStateOrNull( new StateStruct("a", TicNode.CreateTypeVariableNode(StatePrimitive.I32)), new StateStruct("a", TicNode.CreateTypeVariableNode(StatePrimitive.I32))); Assert.AreEqual(res, new StateStruct("a", TicNode.CreateTypeVariableNode(StatePrimitive.I32))); }
public void GetMergedStateOrNull_ConstrainsAndPrimitive_ReturnsPrimitive() { var a = new ConstrainsState(StatePrimitive.U16, StatePrimitive.Real); var b = StatePrimitive.I32; var merged = SolvingFunctions.GetMergedStateOrNull(a, b); Assert.AreEqual(StatePrimitive.I32, merged); }
public void MergeInplace_TwoReferencedPrimitives_Throws() { var a = CreateNode("a", StatePrimitive.I16); var b = CreateNode("b", StatePrimitive.I32); var refA = CreateNode("a", new StateRefTo(a)); var refB = CreateNode("b", new StateRefTo(b)); Assert.Catch(() => SolvingFunctions.MergeInplace(refA, refB)); }
public void MergeInplace_ConstrainsAndPrimitive_ReturnsPrimitive() { var a = CreateNode("a", new ConstrainsState(StatePrimitive.U16, StatePrimitive.Real)); var b = CreateNode("b", StatePrimitive.U32); SolvingFunctions.MergeInplace(a, b); Assert.AreEqual(StatePrimitive.U32, a.State); Assert.AreEqual(StatePrimitive.U32, b.State); }
public void MergeInplace_PrimitiveAndConstrains_ReturnsPrimitive() { var a = CreateNode("a", new ConstrainsState(StatePrimitive.I16, StatePrimitive.Real)); var b = CreateNode("b", StatePrimitive.I64); SolvingFunctions.MergeInplace(b, a); Assert.AreEqual(StatePrimitive.I64, a.State); Assert.AreEqual(StatePrimitive.I64, b.State); }
public void MergeInplace_WhereSecondaryIsReferenced_ReturnsOrigin() { var a = CreateNode("a", new ConstrainsState(StatePrimitive.I16, StatePrimitive.Real)); var refToA = CreateNode("b", new StateRefTo(a)); SolvingFunctions.MergeInplace(a, refToA); Assert.AreEqual(new ConstrainsState(StatePrimitive.I16, StatePrimitive.Real), a.State); Assert.AreEqual(new StateRefTo(a), refToA.State); }
private static void PushFunTypeArgumentsConstraints(StateFun descFun, StateFun ancFun) { for (int i = 0; i < descFun.ArgsCount; i++) { SolvingFunctions.PushConstraints(descFun.ArgNodes[i], ancFun.ArgNodes[i]); } SolvingFunctions.PushConstraints(descFun.RetNode, ancFun.RetNode); }
public void MergeInplace_TwoConstrains_ReturnsMerged() { var a = CreateNode("a", new ConstrainsState(StatePrimitive.I16, StatePrimitive.Real)); var b = CreateNode("b", new ConstrainsState(StatePrimitive.I24, StatePrimitive.Real)); SolvingFunctions.MergeInplace(a, b); Assert.AreEqual(new ConstrainsState(StatePrimitive.I24, StatePrimitive.Real), a.State); Assert.AreEqual(new StateRefTo(a), b.State); }
public void MergeGroup_WithSmallCycle_ReturnsSingle(bool reversedOrder) { //a[i32,r] //r ==> a var a = CreateNode("a", new ConstrainsState(StatePrimitive.I32, StatePrimitive.Real)); var r = CreateNode("r", new StateRefTo(a)); var merged = SolvingFunctions.MergeGroup(reversedOrder?new[] { r, a }: new[] { a, r }); Assert.AreEqual(a, merged); Assert.AreEqual(r.State, new StateRefTo(merged)); Assert.AreEqual(new ConstrainsState(StatePrimitive.I32, StatePrimitive.Real), merged.State); }
public bool Apply(ICompositeState ancestor, ICompositeState descendant, TicNode ancestorNode, TicNode descendantNode) { if (ancestor is StateArray ancArray) { if (descendant is StateArray descArray) { return(SolvingFunctions.Destruction(descArray.ElementNode, ancArray.ElementNode)); } return(true); } if (ancestor is StateFun ancFun) { if (descendant is StateFun descFun) { TraceLog.Write("f+f: "); if (ancFun.ArgsCount == descFun.ArgsCount) { for (int i = 0; i < ancFun.ArgsCount; i++) { SolvingFunctions.Destruction(descFun.ArgNodes[i], ancFun.ArgNodes[i]); } SolvingFunctions.Destruction(ancFun.RetNode, descFun.RetNode); } } } if (ancestor is StateStruct ancStruct) { if (descendant is StateStruct descStruct) { foreach (var ancField in ancStruct.Fields) { var descFieldNode = descStruct.GetFieldOrNull(ancField.Key); if (descFieldNode == null) { //todo!! //throw new ImpossibleException( // $"Struct descendant '{descendantNode.Name}:{descendant}' of node '{ancestorNode.Name}:{ancestor}' miss field '{ancField.Key}'"); descendantNode.State = descStruct.With(ancField.Key, ancField.Value); } else { SolvingFunctions.Destruction(descFieldNode, ancField.Value); } } ancestorNode.State = new StateRefTo(descendantNode); } } return(true); }
public bool Apply(ICompositeState ancestor, ConstrainsState descendant, TicNode ancestorNode, TicNode descendantNode) { if (ancestor is StateArray ancArray) { var result = SolvingFunctions.TransformToArrayOrNull(descendantNode.Name, descendant); if (result == null) { return(false); } result.ElementNode.AddAncestor(ancArray.ElementNode); descendantNode.State = result; descendantNode.RemoveAncestor(ancestorNode); } else if (ancestor is StateFun ancFun) { var result = SolvingFunctions.TransformToFunOrNull( descendantNode.Name, descendant, ancFun); if (result == null) { return(false); } result.RetNode.AddAncestor(ancFun.RetNode); for (int i = 0; i < result.ArgsCount; i++) { result.ArgNodes[i].AddAncestor(ancFun.ArgNodes[i]); } descendantNode.State = result; descendantNode.RemoveAncestor(ancestorNode); } else if (ancestor is StateStruct ancStruct) { var result = SolvingFunctions.TransformToStructOrNull(descendant, ancStruct); if (result == null) { return(false); } //todo Зачем это тут, если и так структура ссылается на оригинальные поля? /*foreach (var ancField in ancStruct.Fields) * { * var descField = result.GetFieldOrNull(ancField.Key); * if (descField != ancField.Value) * { * descField.AddAncestor(ancField.Value); * } * }*/ descendantNode.State = result; //descendantNode.RemoveAncestor(ancestorNode); } return(true); }
private static bool TryMergeStructFields(StateStruct ancStruct, StateStruct descStruct) { foreach (var ancField in ancStruct.Fields) { TicNode descFieldNode = descStruct.GetFieldOrNull(ancField.Key); if (descFieldNode == null) { return(false); } // i m not sure why - but it is very important to set descFieldNode as main merge node... SolvingFunctions.MergeInplace(descFieldNode, ancField.Value); } return(true); }
public void MergeGroup_WithCycle_ReturnsSingle(params int[] order) { //a[i32,r] //b[i24,r] //r ==> a var a = CreateNode("a", new ConstrainsState(StatePrimitive.I32, StatePrimitive.Real)); var b = CreateNode("b", new ConstrainsState(StatePrimitive.I24, StatePrimitive.Real)); var r = CreateNode("r", new StateRefTo(a)); var group = new TicNode[3]; group[order[0]] = a; group[order[1]] = b; group[order[2]] = r; var merged = SolvingFunctions.MergeGroup(group); Assert.AreNotEqual(r, merged); Assert.AreEqual(new ConstrainsState(StatePrimitive.I32, StatePrimitive.Real), merged.State); }
private static void RemoveRefenceCycles(SolvingNode[] nodes) { while (true) { var refList = FindRefNodesGraph(nodes); var arrayOfRefList = refList.ToArray(); var refGraph = ConvertToRefArrayGraph(arrayOfRefList); var refTopology = GraphTools.SortTopology(refGraph); if (!refTopology.HasCycle) { return; } var refCycle = refTopology.NodeNames.Select(n => nodes[n.To]).ToArray(); SolvingFunctions.MergeGroup(refCycle); } }
public void MergeGroup_WithCycle_AncestorsAreCorrect(params int[] order) { //Arrange: //a[i32,r] //b[i24,r] //r ==> a var a = CreateNode("a", new ConstrainsState(StatePrimitive.I32, StatePrimitive.Real)); var b = CreateNode("b", new ConstrainsState(StatePrimitive.I24, StatePrimitive.Real)); var r = CreateNode("r", new StateRefTo(a)); var anc1 = CreateNode("anc1"); var anc2 = CreateNode("anc2"); var anc3 = CreateNode("anc3"); a.AddAncestor(anc1); b.AddAncestor(anc2); r.AddAncestor(anc3); // Shuffle group order var group = new TicNode[3]; group[order[0]] = a; group[order[1]] = b; group[order[2]] = r; //Act: var merged = SolvingFunctions.MergeGroup(group); //Assert: //All non main node have to loose all ancestors foreach (var nonRef in new [] { a, b, r }.Where(i => i != merged)) { Assert.IsEmpty(nonRef.Ancestors); } //All ancestors move to main node Assert.AreEqual(3, merged.Ancestors.Count); Assert.Contains(anc1, merged.Ancestors.ToArray()); Assert.Contains(anc2, merged.Ancestors.ToArray()); Assert.Contains(anc3, merged.Ancestors.ToArray()); }
public void GetMergedStateOrNull_EmptyConstrainsAndPrimitive() { var res = SolvingFunctions.GetMergedStateOrNull(new ConstrainsState(), StatePrimitive.I32); Assert.AreEqual(res, StatePrimitive.I32); }
public bool Apply( ICompositeState ancestor, ConstrainsState descendant, TicNode ancestorNode, TicNode descendantNode) { // if ancestor is composite type then descendant HAS to have same composite type // y:int[] = a:[..] # 'a' has to be an array if (ancestor is StateArray ancArray) { var result = SolvingFunctions.TransformToArrayOrNull(descendantNode.Name, descendant); if (result == null) { return(false); } if (result.ElementNode == ancArray.ElementNode) { descendantNode.RemoveAncestor(ancestorNode); return(true); } result.ElementNode.AddAncestor(ancArray.ElementNode); descendantNode.State = result; descendantNode.RemoveAncestor(ancestorNode); SolvingFunctions.PushConstraints(result.ElementNode, ancArray.ElementNode); return(true); } // y:f(x) = a:[..] # 'a' has to be a functional variable if (ancestor is StateFun ancFun) { var descFun = SolvingFunctions.TransformToFunOrNull(descendantNode.Name, descendant, ancFun); if (descFun == null) { return(false); } if (!descendantNode.State.Equals(descFun)) { descendantNode.State = descFun; PushFunTypeArgumentsConstraints(descFun, ancFun); } return(true); } // y:user = a:[..] # 'a' has to be a struct, that converts to type of 'user' if (ancestor is StateStruct ancStruct) { var descStruct = SolvingFunctions.TransformToStructOrNull(descendant, ancStruct); if (descStruct == null) { return(false); } if (descendantNode.State.Equals(descStruct)) { descendantNode.RemoveAncestor(ancestorNode); return(true); } descendantNode.State = descStruct; if (TryMergeStructFields(ancStruct, descStruct)) { descendantNode.RemoveAncestor(ancestorNode); return(true); } } return(false); }
public void GetMergedState_PrimitiveAndEmptyConstrains() { var res = SolvingFunctions.GetMergedState(Primitive.I32, new Constrains()); Assert.AreEqual(res, Primitive.I32); }
public void GetMergedState_ConstrainsThatFitAndPrimitive() { var res = SolvingFunctions.GetMergedState(new Constrains(Primitive.U24, Primitive.I48), Primitive.I32); Assert.AreEqual(res, Primitive.I32); }
void AssertGetMergedStateIsNull(ITicNodeState stateA, ITicNodeState stateB) { Assert.IsNull(SolvingFunctions.GetMergedStateOrNull(stateA, stateB)); Assert.IsNull(SolvingFunctions.GetMergedStateOrNull(stateB, stateA)); }
public void GetMergedStateOrNull_TwoSamePrimitives() { var res = SolvingFunctions.GetMergedStateOrNull(StatePrimitive.I32, StatePrimitive.I32); Assert.AreEqual(res, StatePrimitive.I32); }
public void GetMergedStateOrNull_ConstrainsThatFitAndPrimitive() { var res = SolvingFunctions.GetMergedStateOrNull(new ConstrainsState(StatePrimitive.U24, StatePrimitive.I48), StatePrimitive.I32); Assert.AreEqual(res, StatePrimitive.I32); }
public void GetMergedStateOrNull_TwoSameConcreteArrays() { var res = SolvingFunctions.GetMergedStateOrNull(StateArray.Of(StatePrimitive.I32), StateArray.Of(StatePrimitive.I32)); Assert.AreEqual(res, StateArray.Of(StatePrimitive.I32)); }