public void SeveralStrictStructMembers() { // 0 2 1 //y:int = a . name // 3 5 4 //z:real = a . age var graph = new GraphBuilder(); graph.SetVar("a", 0); graph.SetFieldAccess(0, 2, "name"); graph.SetVarType("y", StatePrimitive.I32); graph.SetDef("y", 2); graph.SetVar("a", 3); graph.SetFieldAccess(3, 5, "age"); graph.SetVarType("z", StatePrimitive.Real); graph.SetDef("z", 5); var result = graph.Solve(); result.AssertNoGenerics(); result.AssertNamed(new StateStruct(new Dictionary <string, TicNode> { { "name", TicNode.CreateTypeVariableNode(StatePrimitive.I32) }, { "age", TicNode.CreateTypeVariableNode(StatePrimitive.Real) } }), "a"); result.AssertNamed(StatePrimitive.I32, "y"); result.AssertNamed(StatePrimitive.Real, "z"); }
public static void AssertGenericType(this TicNode node, StatePrimitive desc, StatePrimitive anc, bool isComparable = false) { var generic = node.State as ConstrainsState; Assert.IsNotNull(generic); if (desc == null) { Assert.IsFalse(generic.HasDescendant); } else { Assert.AreEqual(desc, generic.Descedant); } if (anc == null) { Assert.IsFalse(generic.HasAncestor); } else { Assert.AreEqual(anc, generic.Ancestor); } Assert.AreEqual(isComparable, generic.IsComparable, "IsComparable claim missed"); }
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 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); }
public void FunCallWithStruct_StructTypeSolved() { // f( input:{field:int} ):bool // // 1 2 // x = @(field = 1) // 4 3 // y = f(x) TraceLog.IsEnabled = true; var graph = new GraphBuilder(); graph.SetIntConst(2, StatePrimitive.U8, StatePrimitive.Real, StatePrimitive.Real); graph.SetStructInit(new[] { "field" }, new[] { 2 }, 1); graph.SetDef("x", 1); graph.SetVar("x", 3); graph.SetCall(new ITicNodeState[] { new StateStruct("field", TicNode.CreateTypeVariableNode(StatePrimitive.I32)), StatePrimitive.Bool }, new[] { 3, 4 }); graph.SetDef("y", 4); var result = graph.Solve(); result.AssertNoGenerics(); result.AssertNamed(StatePrimitive.Bool, "y"); var xStruct = result.GetVariableNode("x").State as StateStruct; var field = xStruct.GetFieldOrNull("field").State as StatePrimitive; Assert.AreEqual(StatePrimitive.I32, field); }
public static void AssertNode(this ITicResults results, TicNode generic, params int[] nodeIds) { foreach (var id in nodeIds) { Assert.AreEqual(generic.GetNonReference(), results.GetSyntaxNodeOrNull(id).GetNonReference()); } }
public bool Apply(ConstrainsState ancestor, ConstrainsState descendant, TicNode ancestorNode, TicNode descendantNode) { var result = ancestor.MergeOrNull(descendant); if (result == null) { return(false); } if (result is StatePrimitive) { descendantNode.State = ancestorNode.State = result; return(true); } if (ancestorNode.Type == TicNodeType.TypeVariable || descendantNode.Type != TicNodeType.TypeVariable) { ancestorNode.State = result; descendantNode.State = new StateRefTo(ancestorNode); } else { descendantNode.State = result; ancestorNode.State = new StateRefTo(descendantNode); } descendantNode.RemoveAncestor(ancestorNode); return(true); }
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 GetLastCommonAncestorOrNull_ConcreteAndNotConcreteType_ReturnsNull() { var funA = StateFun.Of(CreateConstrainsNode(), TicNode.CreateTypeVariableNode(StatePrimitive.I32)); var funB = StateFun.Of(StatePrimitive.U16, StatePrimitive.U64); Assert.IsNull(funA.GetLastCommonAncestorOrNull(funB)); Assert.IsNull(funB.GetLastCommonAncestorOrNull(funA)); }
public void RefState_RefToDifferentNodes_EqualReturnsFalse() { var state1 = new StateRefTo(TicNode.CreateNamedNode("a", new ConstrainsState())); var state2 = new StateRefTo(TicNode.CreateNamedNode("b", new ConstrainsState())); Assert.IsFalse(state1.Equals(state2)); Assert.AreNotEqual(state1, state2); }
public bool Apply(ConstrainsState ancestor, StatePrimitive descendant, TicNode ancestorNode, TicNode descendantNode) { if (ancestor.Fits(descendant)) { ancestorNode.State = descendant; } return(true); }
public static void AssertAreGenerics(this ITicResults result, TicNode targetGenericNode, params string[] varNames) { foreach (var varName in varNames) { Assert.AreEqual(targetGenericNode, result.GetVariableNode(varName).GetNonReference()); } }
public bool Apply(ICompositeState ancestor, ConstrainsState descendant, TicNode ancestorNode, TicNode descendantNode) { if (descendant.Fits(ancestor)) { descendantNode.State = new StateRefTo(ancestorNode); descendantNode.RemoveAncestor(ancestorNode); } return(true); }
public bool Apply(ConstrainsState ancestor, StatePrimitive descendant, TicNode ancestorNode, TicNode descendantNode) { if (!ancestor.HasAncestor) { return(true); } return(descendant.CanBeImplicitlyConvertedTo(ancestor.Ancestor)); }
public void RefState_RefToSameNode_EqualReturnsTrue() { var node = TicNode.CreateNamedNode("a", new ConstrainsState()); var state1 = new StateRefTo(node); var state2 = new StateRefTo(node); Assert.IsTrue(state1.Equals(state2)); Assert.AreEqual(state1, state2); }
public bool Apply(ConstrainsState ancestor, ICompositeState descendant, TicNode ancestorNode, TicNode descendantNode) { //todo Check all nonrefchildren of constrains? if (ancestor.Fits(descendant)) { ancestorNode.State = new StateRefTo(descendantNode); descendantNode.RemoveAncestor(ancestorNode); } return(true); }
static void AssertHasNoAncestorCycleReq(HashSet <TicNode> route, TicNode targetNode) { if (!route.Add(targetNode)) { Assert.Fail($"{targetNode} is in Cycle: {string.Join(",", route)}"); } foreach (var ancestor in targetNode.Ancestors) { AssertHasNoAncestorCycleReq(route, ancestor); } }
public static Exception IncompatibleNodes(TicNode ancestor, TicNode descendant) { if (TryFindSyntaxNode(ancestor, descendant, out int id)) { return(new IncompatibleAncestorSyntaxNodeException(id, ancestor.State, descendant.State)); } if (TryFindNamedNode(ancestor, descendant, out var named)) { return(new IncompatibleAncestorNamedNodeException(named.ToString(), ancestor.State, descendant.State)); } return(new TicNoDetailsException()); }
public static StateFun Of(ITypeState[] argTypes, ITypeState retType) { var argNodes = new TicNode[argTypes.Length]; for (int i = 0; i < argTypes.Length; i++) { argNodes[i] = TicNode.CreateTypeVariableNode(argTypes[i]); } return(new StateFun( argNodes: argNodes, retNode: TicNode.CreateTypeVariableNode(retType))); }
public static Exception CannotSetState(TicNode node, ITicNodeState b) { if (node.Type == TicNodeType.SyntaxNode) { return(new IncompatibleAncestorSyntaxNodeException((int)node.Name, node.State, b)); } if (node.Type == TicNodeType.Named) { return(new IncompatibleAncestorNamedNodeException(node.Name.ToString(), node.State, b)); } return(new TicNoDetailsException()); }
public bool Apply(StatePrimitive ancestor, ConstrainsState descendant, TicNode _, TicNode descendantNode) { descendant.AddAncestor(ancestor); var result = descendant.GetOptimizedOrNull(); if (result == null) { return(false); } descendantNode.State = result; 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); }
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(ConstrainsState ancestor, ConstrainsState descendant, TicNode ancestorNode, TicNode descendantNode) { var ancestorCopy = ancestor.GetCopy(); ancestorCopy.AddDescedant(descendant.Descedant); var result = ancestorCopy.GetOptimizedOrNull(); if (result == null) { return(false); } ancestorNode.State = result; return(true); }
public StateStruct With(string name, TicNode memberNode) { if (memberNode.State is StateRefTo) { } var newDic = new Dictionary <string, TicNode>(_nodes.Count + 1); foreach (var field in _nodes) { newDic.Add(field.Key, field.Value.GetNonReference()); } newDic.Add(name, memberNode); return(new StateStruct(newDic)); }
private static bool ApplyAncestorConstrains(TicNode ancestorNode, ConstrainsState ancestor, ITypeState typeDesc) { var ancestorCopy = ancestor.GetCopy(); ancestorCopy.AddDescedant(typeDesc); var result = ancestorCopy.GetOptimizedOrNull(); if (result == null) { return(false); } ancestorNode.State = result; 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 bool Apply(StatePrimitive ancestor, ConstrainsState descendant, TicNode ancestorNode, TicNode descendantNode) { if (descendant.Fits(ancestor)) { if (descendant.Prefered != null && descendant.Fits(descendant.Prefered)) { descendantNode.State = descendant.Prefered; } else { descendantNode.State = ancestor; } } return(true); }
private static bool TryFindSyntaxNode(TicNode ancestor, TicNode descendant, out int syntaxNode) { syntaxNode = -1; if (descendant.Type == TicNodeType.SyntaxNode) { syntaxNode = (int)descendant.Name; return(true); } if (ancestor.Type == TicNodeType.SyntaxNode) { syntaxNode = (int)ancestor.Name; return(true); } return(false); }