1519 |
1519 |
1520 module Isabelle.Completion ( |
1520 module Isabelle.Completion ( |
1521 Name, T, names, none, make, markup_element, markup_report, make_report |
1521 Name, T, names, none, make, markup_element, markup_report, make_report |
1522 ) where |
1522 ) where |
1523 |
1523 |
1524 import Isabelle.Library |
|
1525 import qualified Isabelle.Bytes as Bytes |
1524 import qualified Isabelle.Bytes as Bytes |
1526 import Isabelle.Bytes (Bytes) |
1525 import qualified Isabelle.Name as Name |
|
1526 import Isabelle.Name (Name) |
1527 import qualified Isabelle.Properties as Properties |
1527 import qualified Isabelle.Properties as Properties |
1528 import qualified Isabelle.Markup as Markup |
1528 import qualified Isabelle.Markup as Markup |
1529 import qualified Isabelle.XML.Encode as Encode |
1529 import qualified Isabelle.XML.Encode as Encode |
1530 import qualified Isabelle.XML as XML |
1530 import qualified Isabelle.XML as XML |
1531 import qualified Isabelle.YXML as YXML |
1531 import qualified Isabelle.YXML as YXML |
1532 |
1532 |
1533 |
1533 |
1534 type Name = (Bytes, (Bytes, Bytes)) -- external name, kind, internal name |
1534 type Names = [(Name, (Name, Name))] -- external name, kind, internal name |
1535 data T = Completion Properties.T Int [Name] -- position, total length, names |
1535 data T = Completion Properties.T Int Names -- position, total length, names |
1536 |
1536 |
1537 names :: Int -> Properties.T -> [Name] -> T |
1537 names :: Int -> Properties.T -> Names -> T |
1538 names limit props names = Completion props (length names) (take limit names) |
1538 names limit props names = Completion props (length names) (take limit names) |
1539 |
1539 |
1540 none :: T |
1540 none :: T |
1541 none = names 0 [] [] |
1541 none = names 0 [] [] |
1542 |
1542 |
1543 clean_name :: Bytes -> Bytes |
1543 make :: Int -> (Name, Properties.T) -> ((Name -> Bool) -> Names) -> T |
1544 clean_name bs = |
|
1545 if not (Bytes.null bs) && Bytes.last bs == u then |
|
1546 Bytes.unpack bs |> reverse |> dropWhile (== u) |> reverse |> Bytes.pack |
|
1547 else bs |
|
1548 where u = Bytes.byte '_' |
|
1549 |
|
1550 make :: Int -> (Bytes, Properties.T) -> ((Bytes -> Bool) -> [Name]) -> T |
|
1551 make limit (name, props) make_names = |
1544 make limit (name, props) make_names = |
1552 if name /= "" && name /= "_" then |
1545 if name /= "" && name /= "_" then |
1553 names limit props (make_names (Bytes.isPrefixOf (clean_name name))) |
1546 names limit props (make_names (Bytes.isPrefixOf (Name.clean name))) |
1554 else none |
1547 else none |
1555 |
1548 |
1556 markup_element :: T -> (Markup.T, XML.Body) |
1549 markup_element :: T -> (Markup.T, XML.Body) |
1557 markup_element (Completion props total names) = |
1550 markup_element (Completion props total names) = |
1558 if not (null names) then |
1551 if not (null names) then |
1758 |
1751 |
1759 big_list :: BYTES a => a -> [T] -> T |
1752 big_list :: BYTES a => a -> [T] -> T |
1760 big_list name prts = block (fbreaks (str name : prts)) |
1753 big_list name prts = block (fbreaks (str name : prts)) |
1761 \<close> |
1754 \<close> |
1762 |
1755 |
|
1756 generate_file "Isabelle/Name.hs" = \<open> |
|
1757 {- Title: Isabelle/Name.hs |
|
1758 Author: Makarius |
|
1759 |
|
1760 Names of basic logical entities (variables etc.). |
|
1761 |
|
1762 See also \<^file>\<open>$ISABELLE_HOME/src/Pure/name.ML\<close>. |
|
1763 -} |
|
1764 |
|
1765 {-# LANGUAGE OverloadedStrings #-} |
|
1766 |
|
1767 module Isabelle.Name ( |
|
1768 Name, clean_index, clean, |
|
1769 Context, declare, is_declared, context, make_context, variant |
|
1770 ) |
|
1771 where |
|
1772 |
|
1773 import Data.Word (Word8) |
|
1774 import qualified Data.Set as Set |
|
1775 import Data.Set (Set) |
|
1776 import qualified Isabelle.Bytes as Bytes |
|
1777 import Isabelle.Bytes (Bytes) |
|
1778 import qualified Isabelle.Symbol as Symbol |
|
1779 import Isabelle.Library |
|
1780 |
|
1781 |
|
1782 type Name = Bytes |
|
1783 |
|
1784 |
|
1785 {- suffix for internal names -} |
|
1786 |
|
1787 underscore :: Word8 |
|
1788 underscore = Bytes.byte '_' |
|
1789 |
|
1790 clean_index :: Name -> (Name, Int) |
|
1791 clean_index x = |
|
1792 if Bytes.null x || Bytes.last x /= underscore then (x, 0) |
|
1793 else |
|
1794 let |
|
1795 rev = reverse (Bytes.unpack x) |
|
1796 n = length (takeWhile (== underscore) rev) |
|
1797 y = Bytes.pack (reverse (drop n rev)) |
|
1798 in (y, n) |
|
1799 |
|
1800 clean :: Name -> Name |
|
1801 clean = fst . clean_index |
|
1802 |
|
1803 |
|
1804 {- context for used names -} |
|
1805 |
|
1806 data Context = Context (Set Name) |
|
1807 |
|
1808 declare :: Name -> Context -> Context |
|
1809 declare x (Context names) = Context (Set.insert x names) |
|
1810 |
|
1811 is_declared :: Context -> Name -> Bool |
|
1812 is_declared (Context names) x = Set.member x names |
|
1813 |
|
1814 context :: Context |
|
1815 context = Context (Set.fromList ["", "'"]) |
|
1816 |
|
1817 make_context :: [Name] -> Context |
|
1818 make_context used = fold declare used context |
|
1819 |
|
1820 |
|
1821 {- generating fresh names -} |
|
1822 |
|
1823 bump_init :: Name -> Name |
|
1824 bump_init str = str <> "a" |
|
1825 |
|
1826 bump_string :: Name -> Name |
|
1827 bump_string str = |
|
1828 let |
|
1829 a = Bytes.byte 'a' |
|
1830 z = Bytes.byte 'z' |
|
1831 bump (b : bs) | b == z = a : bump bs |
|
1832 bump (b : bs) | a <= b && b < z = b + 1 : bs |
|
1833 bump bs = a : bs |
|
1834 |
|
1835 rev = reverse (Bytes.unpack str) |
|
1836 part2 = reverse (takeWhile (Symbol.is_ascii_quasi . Bytes.char) rev) |
|
1837 part1 = reverse (bump (drop (length part2) rev)) |
|
1838 in Bytes.pack (part1 <> part2) |
|
1839 |
|
1840 variant :: Name -> Context -> (Name, Context) |
|
1841 variant name names = |
|
1842 let |
|
1843 vary bump x = if is_declared names x then bump x |> vary bump_string else x |
|
1844 (x, n) = clean_index name |
|
1845 x' = x |> vary bump_init |
|
1846 names' = declare x' names; |
|
1847 in (x' <> Bytes.pack (replicate n underscore), names') |
|
1848 \<close> |
|
1849 |
1763 generate_file "Isabelle/Term.hs" = \<open> |
1850 generate_file "Isabelle/Term.hs" = \<open> |
1764 {- Title: Isabelle/Term.hs |
1851 {- Title: Isabelle/Term.hs |
1765 Author: Makarius |
1852 Author: Makarius |
1766 LICENSE: BSD 3-clause (Isabelle) |
1853 LICENSE: BSD 3-clause (Isabelle) |
1767 |
1854 |
1807 | Bound Int |
1895 | Bound Int |
1808 | Abs (Name, Typ, Term) |
1896 | Abs (Name, Typ, Term) |
1809 | App (Term, Term) |
1897 | App (Term, Term) |
1810 deriving (Show, Eq, Ord) |
1898 deriving (Show, Eq, Ord) |
1811 |
1899 |
|
1900 |
|
1901 {- free and bound variables -} |
|
1902 |
1812 type Free = (Name, Typ) |
1903 type Free = (Name, Typ) |
1813 |
|
1814 |
|
1815 {- type and term operators -} |
|
1816 |
|
1817 type_op0 :: Name -> (Typ, Typ -> Bool) |
|
1818 type_op0 name = (mk, is) |
|
1819 where |
|
1820 mk = Type (name, []) |
|
1821 is (Type (name, _)) = True |
|
1822 is _ = False |
|
1823 |
|
1824 type_op1 :: Name -> (Typ -> Typ, Typ -> Maybe Typ) |
|
1825 type_op1 name = (mk, dest) |
|
1826 where |
|
1827 mk ty = Type (name, [ty]) |
|
1828 dest (Type (name, [ty])) = Just ty |
|
1829 dest _ = Nothing |
|
1830 |
|
1831 type_op2 :: Name -> (Typ -> Typ -> Typ, Typ -> Maybe (Typ, Typ)) |
|
1832 type_op2 name = (mk, dest) |
|
1833 where |
|
1834 mk ty1 ty2 = Type (name, [ty1, ty2]) |
|
1835 dest (Type (name, [ty1, ty2])) = Just (ty1, ty2) |
|
1836 dest _ = Nothing |
|
1837 |
|
1838 op0 :: Name -> (Term, Term -> Bool) |
|
1839 op0 name = (mk, is) |
|
1840 where |
|
1841 mk = Const (name, []) |
|
1842 is (Const (c, _)) = c == name |
|
1843 is _ = False |
|
1844 |
|
1845 op1 :: Name -> (Term -> Term, Term -> Maybe Term) |
|
1846 op1 name = (mk, dest) |
|
1847 where |
|
1848 mk t = App (Const (name, []), t) |
|
1849 dest (App (Const (c, _), t)) | c == name = Just t |
|
1850 dest _ = Nothing |
|
1851 |
|
1852 op2 :: Name -> (Term -> Term -> Term, Term -> Maybe (Term, Term)) |
|
1853 op2 name = (mk, dest) |
|
1854 where |
|
1855 mk t u = App (App (Const (name, []), t), u) |
|
1856 dest (App (App (Const (c, _), t), u)) | c == name = Just (t, u) |
|
1857 dest _ = Nothing |
|
1858 |
|
1859 typed_op2 :: Name -> (Typ -> Term -> Term -> Term, Term -> Maybe (Typ, Term, Term)) |
|
1860 typed_op2 name = (mk, dest) |
|
1861 where |
|
1862 mk ty t u = App (App (Const (name, [ty]), t), u) |
|
1863 dest (App (App (Const (c, [ty]), t), u)) | c == name = Just (ty, t, u) |
|
1864 dest _ = Nothing |
|
1865 |
|
1866 binder :: Name -> Free -> Term -> Term |
|
1867 binder c (a, ty) b = App (Const (c, [ty]), lambda (a, ty) b) |
|
1868 |
|
1869 |
|
1870 {- type operations -} |
|
1871 |
|
1872 dummyS :: Sort |
|
1873 dummyS = [""] |
|
1874 |
|
1875 dummyT :: Typ; is_dummyT :: Typ -> Bool |
|
1876 (dummyT, is_dummyT) = type_op0 \<open>\<^type_name>\<open>dummy\<close>\<close> |
|
1877 |
|
1878 propT :: Typ; is_propT :: Typ -> Bool |
|
1879 (propT, is_propT) = type_op0 \<open>\<^type_name>\<open>prop\<close>\<close> |
|
1880 |
|
1881 (-->) :: Typ -> Typ -> Typ; dest_funT :: Typ -> Maybe (Typ, Typ) |
|
1882 ((-->), dest_funT) = type_op2 \<open>\<^type_name>\<open>fun\<close>\<close> |
|
1883 |
|
1884 (--->) :: [Typ] -> Typ -> Typ |
|
1885 [] ---> b = b |
|
1886 (a : as) ---> b = a --> (as ---> b) |
|
1887 |
|
1888 |
|
1889 {- term operations -} |
|
1890 |
|
1891 aconv :: Term -> Term -> Bool |
|
1892 aconv (App (t1, u1)) (App (t2, u2)) = aconv t1 t2 && aconv u1 u2 |
|
1893 aconv (Abs (_, ty1, t1)) (Abs (_, ty2, t2)) = aconv t1 t2 && ty1 == ty2 |
|
1894 aconv a1 a2 = a1 == a2 |
|
1895 |
|
1896 list_comb :: Term -> [Term] -> Term |
|
1897 list_comb f [] = f |
|
1898 list_comb f (t : ts) = list_comb (App (f, t)) ts |
|
1899 |
|
1900 strip_comb :: Term -> (Term, [Term]) |
|
1901 strip_comb tm = strip (tm, []) |
|
1902 where |
|
1903 strip (App (f, t), ts) = strip (f, t : ts) |
|
1904 strip x = x |
|
1905 |
|
1906 head_of :: Term -> Term |
|
1907 head_of (App (f, _)) = head_of f |
|
1908 head_of u = u |
|
1909 |
1904 |
1910 lambda :: Free -> Term -> Term |
1905 lambda :: Free -> Term -> Term |
1911 lambda (name, typ) body = Abs (name, typ, abstract 0 body) |
1906 lambda (name, typ) body = Abs (name, typ, abstract 0 body) |
1912 where |
1907 where |
1913 abstract lev (Free (x, ty)) | name == x && typ == ty = Bound lev |
1908 abstract lev (Free (x, ty)) | name == x && typ == ty = Bound lev |
1914 abstract lev (Abs (a, ty, t)) = Abs (a, ty, abstract (lev + 1) t) |
1909 abstract lev (Abs (a, ty, t)) = Abs (a, ty, abstract (lev + 1) t) |
1915 abstract lev (App (t, u)) = App (abstract lev t, abstract lev u) |
1910 abstract lev (App (t, u)) = App (abstract lev t, abstract lev u) |
1916 abstract _ t = t |
1911 abstract _ t = t |
|
1912 |
|
1913 declare_frees :: Term -> Name.Context -> Name.Context |
|
1914 declare_frees (Free (x, _)) = Name.declare x |
|
1915 declare_frees (Abs (_, _, b)) = declare_frees b |
|
1916 declare_frees (App (t, u)) = declare_frees t #> declare_frees u |
|
1917 declare_frees _ = id |
|
1918 |
|
1919 incr_boundvars :: Int -> Term -> Term |
|
1920 incr_boundvars inc = if inc == 0 then id else incr 0 |
|
1921 where |
|
1922 incr lev (Bound i) = if i >= lev then Bound (i + inc) else Bound i |
|
1923 incr lev (Abs (a, ty, b)) = Abs (a, ty, incr (lev + 1) b) |
|
1924 incr lev (App (t, u)) = App (incr lev t, incr lev u) |
|
1925 incr _ t = t |
|
1926 |
|
1927 subst_bound :: Term -> Term -> Term |
|
1928 subst_bound arg = subst 0 |
|
1929 where |
|
1930 subst lev (Bound i) = |
|
1931 if i < lev then Bound i |
|
1932 else if i == lev then incr_boundvars lev arg |
|
1933 else Bound (i - 1) |
|
1934 subst lev (Abs (a, ty, b)) = Abs (a, ty, subst (lev + 1) b) |
|
1935 subst lev (App (t, u)) = App (subst lev t, subst lev u) |
|
1936 subst _ t = t |
|
1937 |
|
1938 dest_abs :: Name.Context -> Term -> Maybe (Free, Term) |
|
1939 dest_abs names (Abs (x, ty, b)) = |
|
1940 let |
|
1941 (x', _) = Name.variant x (declare_frees b names) |
|
1942 v = (x', ty) |
|
1943 in Just (v, subst_bound (Free v) b) |
|
1944 dest_abs _ _ = Nothing |
|
1945 |
|
1946 |
|
1947 {- type and term operators -} |
|
1948 |
|
1949 type_op0 :: Name -> (Typ, Typ -> Bool) |
|
1950 type_op0 name = (mk, is) |
|
1951 where |
|
1952 mk = Type (name, []) |
|
1953 is (Type (name, _)) = True |
|
1954 is _ = False |
|
1955 |
|
1956 type_op1 :: Name -> (Typ -> Typ, Typ -> Maybe Typ) |
|
1957 type_op1 name = (mk, dest) |
|
1958 where |
|
1959 mk ty = Type (name, [ty]) |
|
1960 dest (Type (name, [ty])) = Just ty |
|
1961 dest _ = Nothing |
|
1962 |
|
1963 type_op2 :: Name -> (Typ -> Typ -> Typ, Typ -> Maybe (Typ, Typ)) |
|
1964 type_op2 name = (mk, dest) |
|
1965 where |
|
1966 mk ty1 ty2 = Type (name, [ty1, ty2]) |
|
1967 dest (Type (name, [ty1, ty2])) = Just (ty1, ty2) |
|
1968 dest _ = Nothing |
|
1969 |
|
1970 op0 :: Name -> (Term, Term -> Bool) |
|
1971 op0 name = (mk, is) |
|
1972 where |
|
1973 mk = Const (name, []) |
|
1974 is (Const (c, _)) = c == name |
|
1975 is _ = False |
|
1976 |
|
1977 op1 :: Name -> (Term -> Term, Term -> Maybe Term) |
|
1978 op1 name = (mk, dest) |
|
1979 where |
|
1980 mk t = App (Const (name, []), t) |
|
1981 dest (App (Const (c, _), t)) | c == name = Just t |
|
1982 dest _ = Nothing |
|
1983 |
|
1984 op2 :: Name -> (Term -> Term -> Term, Term -> Maybe (Term, Term)) |
|
1985 op2 name = (mk, dest) |
|
1986 where |
|
1987 mk t u = App (App (Const (name, []), t), u) |
|
1988 dest (App (App (Const (c, _), t), u)) | c == name = Just (t, u) |
|
1989 dest _ = Nothing |
|
1990 |
|
1991 typed_op2 :: Name -> (Typ -> Term -> Term -> Term, Term -> Maybe (Typ, Term, Term)) |
|
1992 typed_op2 name = (mk, dest) |
|
1993 where |
|
1994 mk ty t u = App (App (Const (name, [ty]), t), u) |
|
1995 dest (App (App (Const (c, [ty]), t), u)) | c == name = Just (ty, t, u) |
|
1996 dest _ = Nothing |
|
1997 |
|
1998 binder :: Name -> Free -> Term -> Term |
|
1999 binder c (a, ty) b = App (Const (c, [ty]), lambda (a, ty) b) |
|
2000 |
|
2001 |
|
2002 {- type operations -} |
|
2003 |
|
2004 dummyS :: Sort |
|
2005 dummyS = [""] |
|
2006 |
|
2007 dummyT :: Typ; is_dummyT :: Typ -> Bool |
|
2008 (dummyT, is_dummyT) = type_op0 \<open>\<^type_name>\<open>dummy\<close>\<close> |
|
2009 |
|
2010 propT :: Typ; is_propT :: Typ -> Bool |
|
2011 (propT, is_propT) = type_op0 \<open>\<^type_name>\<open>prop\<close>\<close> |
|
2012 |
|
2013 (-->) :: Typ -> Typ -> Typ; dest_funT :: Typ -> Maybe (Typ, Typ) |
|
2014 ((-->), dest_funT) = type_op2 \<open>\<^type_name>\<open>fun\<close>\<close> |
|
2015 |
|
2016 (--->) :: [Typ] -> Typ -> Typ |
|
2017 [] ---> b = b |
|
2018 (a : as) ---> b = a --> (as ---> b) |
|
2019 |
|
2020 |
|
2021 {- term operations -} |
|
2022 |
|
2023 aconv :: Term -> Term -> Bool |
|
2024 aconv (App (t1, u1)) (App (t2, u2)) = aconv t1 t2 && aconv u1 u2 |
|
2025 aconv (Abs (_, ty1, t1)) (Abs (_, ty2, t2)) = aconv t1 t2 && ty1 == ty2 |
|
2026 aconv a1 a2 = a1 == a2 |
|
2027 |
|
2028 list_comb :: Term -> [Term] -> Term |
|
2029 list_comb f [] = f |
|
2030 list_comb f (t : ts) = list_comb (App (f, t)) ts |
|
2031 |
|
2032 strip_comb :: Term -> (Term, [Term]) |
|
2033 strip_comb tm = strip (tm, []) |
|
2034 where |
|
2035 strip (App (f, t), ts) = strip (f, t : ts) |
|
2036 strip x = x |
|
2037 |
|
2038 head_of :: Term -> Term |
|
2039 head_of (App (f, _)) = head_of f |
|
2040 head_of u = u |
1917 \<close> |
2041 \<close> |
1918 |
2042 |
1919 generate_file "Isabelle/Pure.hs" = \<open> |
2043 generate_file "Isabelle/Pure.hs" = \<open> |
1920 {- Title: Isabelle/Term.hs |
2044 {- Title: Isabelle/Term.hs |
1921 Author: Makarius |
2045 Author: Makarius |