@@ -753,6 +753,7 @@ package body Langkit_Support.Adalog.Solver is
753
753
when Assign | True | False => True,
754
754
755
755
when Propagate => Append_Definition (Atom.From),
756
+ when N_Propagate => Append_Definitions (Atom.Comb_Vars),
756
757
when Predicate => Append_Definition (Atom.Target),
757
758
when N_Predicate => Append_Definitions (Atom.Vars),
758
759
@@ -972,10 +973,15 @@ package body Langkit_Support.Adalog.Solver is
972
973
is
973
974
-- We handle Unify here, even though it is not strictly treated in the
974
975
-- dependency graph, so that the Unify_From variable is registered in
975
- -- the list of variables of the equation. TODO??? Might be cleaner to
976
- -- have a separate function to return all variables a relation uses?
976
+ -- the list of variables of the equation.
977
+ --
978
+ -- We also pretend that N_Propagate has no dependency here because it
979
+ -- depends on multiple variables. Callers should handle it separately.
980
+ --
981
+ -- TODO??? Might be cleaner to have a separate function to return all
982
+ -- variables a relation uses?
977
983
(case Self.Kind is
978
- when Assign | True | False | N_Predicate => null ,
984
+ when Assign | N_Propagate | True | False | N_Predicate => null ,
979
985
when Propagate => Self.From,
980
986
when Predicate => Self.Target,
981
987
when Unify => Self.Unify_From);
@@ -991,8 +997,8 @@ package body Langkit_Support.Adalog.Solver is
991
997
-- the list of variables of the equation. TODO??? Might be cleaner to
992
998
-- have a separate function to return all variables a relation defines?
993
999
(case Self.Kind is
994
- when Assign | Propagate | Unify => Self.Target,
995
- when Predicate | True | False | N_Predicate => null );
1000
+ when Assign | Propagate | N_Propagate | Unify => Self.Target,
1001
+ when Predicate | True | False | N_Predicate => null );
996
1002
997
1003
-- ---------------
998
1004
-- To_Relation --
@@ -1683,6 +1689,27 @@ package body Langkit_Support.Adalog.Solver is
1683
1689
Debug_String => Debug_String);
1684
1690
end Create_Propagate ;
1685
1691
1692
+ -- ----------------------
1693
+ -- Create_N_Propagate --
1694
+ -- ----------------------
1695
+
1696
+ function Create_N_Propagate
1697
+ (To : Logic_Var;
1698
+ Comb : Combiner_Type'Class;
1699
+ Logic_Vars : Logic_Var_Array;
1700
+ Debug_String : String_Access := null ) return Relation
1701
+ is
1702
+ Vars_Vec : Logic_Var_Vector := Logic_Var_Vectors.Empty_Vector;
1703
+ begin
1704
+ Vars_Vec.Concat (Logic_Var_Vectors.Elements_Array (Logic_Vars));
1705
+ return To_Relation
1706
+ (Atomic_Relation_Type'(Kind => N_Propagate,
1707
+ Comb_Vars => Vars_Vec,
1708
+ Comb => new Combiner_Type'Class'(Comb),
1709
+ Target => To),
1710
+ Debug_String => Debug_String);
1711
+ end Create_N_Propagate ;
1712
+
1686
1713
-- --------------------
1687
1714
-- Create_Propagate --
1688
1715
-- --------------------
@@ -1803,6 +1830,10 @@ package body Langkit_Support.Adalog.Solver is
1803
1830
end if ;
1804
1831
Free (Self.Conv);
1805
1832
1833
+ when N_Propagate =>
1834
+ Destroy (Self.Comb.all );
1835
+ Free (Self.Comb);
1836
+
1806
1837
when Predicate =>
1807
1838
Destroy (Self.Pred.all );
1808
1839
Free (Self.Pred);
@@ -1852,6 +1883,14 @@ package body Langkit_Support.Adalog.Solver is
1852
1883
function Solve_Atomic (Self : Atomic_Relation) return Boolean is
1853
1884
Atom : Atomic_Relation_Type renames Self.Atomic_Rel;
1854
1885
1886
+ function Converted_Val (Val : Value_Type) return Value_Type
1887
+ is
1888
+ (if Atom.Conv /= null
1889
+ then Atom.Conv.Convert_Wrapper (Val)
1890
+ else Val);
1891
+ -- Assuming ``Atom`` is an Assign or Propagate atom, return ``Val``
1892
+ -- transformed by its converter.
1893
+
1855
1894
function Assign_Val (Val : Value_Type) return Boolean;
1856
1895
-- Tries to assign ``Val`` to ``Atom.Target`` and return True either if
1857
1896
-- ``Atom.Target`` already has a value compatible with ``Val``, or if
@@ -1860,33 +1899,56 @@ package body Langkit_Support.Adalog.Solver is
1860
1899
-- This assumes that ``Self`` is either an ``Assign`` or a `Propagate``
1861
1900
-- relation.
1862
1901
1902
+ procedure Get_Values (Vars : Logic_Var_Vector; Vals : out Value_Array);
1903
+ -- Assign to ``Vals`` the value of the variables in ``Vars``.
1904
+ --
1905
+ -- This assumes that ``Vars`` and ``Vals`` have the same bounds. Note
1906
+ -- that we could turn this into a function that returns the array, but
1907
+ -- this would require secondary stack support and its overhead, whereas
1908
+ -- this is performance critical code.
1909
+
1863
1910
-- --------------
1864
1911
-- Assign_Val --
1865
1912
-- --------------
1866
1913
1867
1914
function Assign_Val (Val : Value_Type) return Boolean is
1868
- Conv_Val : constant Value_Type :=
1869
- (if Atom.Conv /= null
1870
- then Atom.Conv.Convert_Wrapper (Val)
1871
- else Val);
1872
1915
begin
1873
1916
if Is_Defined (Atom.Target) then
1874
- return Conv_Val = Get_Value (Atom.Target);
1917
+ return Val = Get_Value (Atom.Target);
1875
1918
else
1876
- Set_Value (Atom.Target, Conv_Val );
1919
+ Set_Value (Atom.Target, Val );
1877
1920
return True;
1878
1921
end if ;
1879
1922
end Assign_Val ;
1880
1923
1924
+ -- --------------
1925
+ -- Get_Values --
1926
+ -- --------------
1927
+
1928
+ procedure Get_Values (Vars : Logic_Var_Vector; Vals : out Value_Array) is
1929
+ begin
1930
+ for I in Vals'Range loop
1931
+ Vals (I) := Get_Value (Vars.Get (I));
1932
+ end loop ;
1933
+ end Get_Values ;
1934
+
1881
1935
Ret : Boolean;
1882
1936
begin
1883
1937
case Atom.Kind is
1884
1938
when Assign =>
1885
- Ret := Assign_Val (Atom.Val);
1939
+ Ret := Assign_Val (Converted_Val ( Atom.Val) );
1886
1940
1887
1941
when Propagate =>
1888
1942
pragma Assert (Is_Defined (Atom.From));
1889
- Ret := Assign_Val (Get_Value (Atom.From));
1943
+ Ret := Assign_Val (Converted_Val (Get_Value (Atom.From)));
1944
+
1945
+ when N_Propagate =>
1946
+ declare
1947
+ Vals : Value_Array (1 .. Atom.Comb_Vars.Length);
1948
+ begin
1949
+ Get_Values (Atom.Comb_Vars, Vals);
1950
+ Ret := Assign_Val (Atom.Comb.Combine_Wrapper (Vals));
1951
+ end ;
1890
1952
1891
1953
when Predicate =>
1892
1954
pragma Assert (Is_Defined (Atom.Target));
@@ -1896,10 +1958,7 @@ package body Langkit_Support.Adalog.Solver is
1896
1958
declare
1897
1959
Vals : Value_Array (1 .. Atom.Vars.Length);
1898
1960
begin
1899
- for I in Atom.Vars.First_Index .. Atom.Vars.Last_Index loop
1900
- Vals (I) := Get_Value (Atom.Vars.Get (I));
1901
- end loop ;
1902
-
1961
+ Get_Values (Atom.Vars, Vals);
1903
1962
Ret := Atom.N_Pred.Call_Wrapper (Vals);
1904
1963
end ;
1905
1964
@@ -1931,6 +1990,22 @@ package body Langkit_Support.Adalog.Solver is
1931
1990
function Prop_Image (Left, Right : String) return String
1932
1991
is
1933
1992
(Left & " <- " & Right_Image (Right));
1993
+
1994
+ function Var_Args_Image (Vars : Logic_Var_Vector) return String;
1995
+
1996
+ -- ------------------
1997
+ -- Var_Args_Image --
1998
+ -- ------------------
1999
+
2000
+ function Var_Args_Image (Vars : Logic_Var_Vector) return String is
2001
+ Vars_Image : XString_Array (1 .. Vars.Length);
2002
+ begin
2003
+ for I in Vars_Image'Range loop
2004
+ Vars_Image (I) := To_XString (Image (Vars.Get (I)));
2005
+ end loop ;
2006
+ return " (" & To_XString (" , " ).Join (Vars_Image).To_String & " )" ;
2007
+ end Var_Args_Image ;
2008
+
1934
2009
begin
1935
2010
case Self.Kind is
1936
2011
when Propagate =>
@@ -1940,6 +2015,10 @@ package body Langkit_Support.Adalog.Solver is
1940
2015
return Prop_Image
1941
2016
(Image (Self.Target), Logic_Vars.Value_Image (Self.Val));
1942
2017
2018
+ when N_Propagate =>
2019
+ return Image (Self.Target) & " <- " & Self.Comb.Image
2020
+ & Var_Args_Image (Self.Comb_Vars);
2021
+
1943
2022
when Predicate =>
1944
2023
declare
1945
2024
Full_Img : constant String :=
@@ -1954,16 +2033,11 @@ package body Langkit_Support.Adalog.Solver is
1954
2033
declare
1955
2034
Full_Img : constant String :=
1956
2035
Self.N_Pred.Full_Image (Logic_Var_Array (Self.Vars.To_Array));
1957
- Vars_Image : XString_Array (1 .. Self.Vars.Length);
1958
2036
begin
1959
- if Full_Img /= " " then
1960
- return Full_Img;
1961
- end if ;
1962
- for I in Vars_Image'Range loop
1963
- Vars_Image (I) := To_XString (Image (Self.Vars.Get (I)));
1964
- end loop ;
1965
- return Self.N_Pred.Image
1966
- & " ?(" & To_XString (" , " ).Join (Vars_Image).To_String & " )" ;
2037
+ return
2038
+ (if Full_Img /= " "
2039
+ then Full_Img
2040
+ else Self.N_Pred.Image & " ?" & Var_Args_Image (Self.Vars));
1967
2041
end ;
1968
2042
1969
2043
when True =>
0 commit comments