@@ -462,6 +462,11 @@ external func same_term A, A.
462462func (==) A, A.
463463X == Y :- same_term X Y.
464464
465+ % Unification without occur check. It can create infinite terms.
466+ :nooc
467+ func unsound_unif -> A, A.
468+ unsound_unif X X.
469+
465470
466471% [cmp_term A B Cmp] Compares A and B. Only works if A and B are ground.
467472external func cmp_term any, any -> cmp.
@@ -1276,6 +1281,136 @@ bindings (node L V D R _) X X1 :-
12761281} % std.map.private
12771282} % std.map
12781283
1284+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1285+
1286+ % Fast maps only work ground terms but do not perform occur check
1287+
1288+ kind std.fmap type -> type -> type.
1289+ type std.fmap std.fmap.private.map K V -> (func K, K -> cmp) -> std.fmap K V.
1290+
1291+ namespace std.fmap {
1292+
1293+ % [make Eq Ltn M] builds an empty map M where keys are compared using Eq and Ltn
1294+ func make (func K, K -> cmp) -> std.fmap K V.
1295+ make Cmp (std.fmap private.empty Cmp).
1296+
1297+ % [find K M V] looks in M for the value V associated to K
1298+ func find K, std.fmap K V -> V.
1299+ find K (std.fmap M Cmp) V :-
1300+ private.assert-ground K,
1301+ private.find M Cmp K V.
1302+
1303+ % [add K V M M1] M1 is M where K is bound to V
1304+ func add K, V, std.fmap K V -> std.fmap K V.
1305+ add K V (std.fmap M Cmp) R :-
1306+ private.assert-ground K,
1307+ private.assert-ground V,
1308+ private.add M Cmp K V M1,
1309+ unsound_unif R (std.fmap M1 Cmp).
1310+
1311+ % [remove K M M1] M1 is M where K is unbound
1312+ func remove K, std.fmap K V -> std.fmap K V.
1313+ remove K (std.fmap M Cmp) R :-
1314+ private.assert-ground K,
1315+ private.remove M Cmp K M1,
1316+ unsound_unif R (std.fmap M1 Cmp).
1317+
1318+ % [bindings M L] L is the key-value pairs in increasing order
1319+ func bindings std.fmap K V -> list (pair K V).
1320+ bindings (std.fmap M _) L :- private.bindings M [] L.
1321+
1322+ namespace private {
1323+
1324+ func assert-ground A.
1325+ assert-ground A :- std.assert! (ground_term A) "std.fmap: not ground".
1326+
1327+ % Taken from OCaml's map.ml
1328+ kind map type -> type -> type.
1329+ type empty map K V.
1330+ type node map K V -> K -> V -> map K V -> int -> map K V.
1331+
1332+ func height map K V -> int.
1333+ height empty 0.
1334+ height (node _ _ _ _ H) H.
1335+
1336+ func create map K V, K, V, map K V -> map K V.
1337+ create L K V R X :-
1338+ H is {std.max {height L} {height R}} + 1,
1339+ unsound_unif X (node L K V R H).
1340+
1341+ func bal map K V, K, V, map K V -> map K V.
1342+ bal L K V R T :-
1343+ height L HL,
1344+ height R HR,
1345+ HL2 is HL + 2,
1346+ HR2 is HR + 2,
1347+ bal.aux HL HR HL2 HR2 L K V R T.
1348+
1349+ func bal.aux int, int, int, int, map K V, K, V, map K V -> map K V.
1350+ bal.aux HL _ _ HR2 (node LL LV LD LR _) X D R T :-
1351+ HL > HR2, {height LL} >= {height LR}, !,
1352+ create LL LV LD {create LR X D R} T.
1353+ bal.aux HL _ _ HR2 (node LL LV LD (node LRL LRV LRD LRR _) _) X D R T :-
1354+ HL > HR2, !,
1355+ create {create LL LV LD LRL} LRV LRD {create LRR X D R} T.
1356+ bal.aux _ HR HL2 _ L X D (node RL RV RD RR _) T :-
1357+ HR > HL2, {height RR} >= {height RL}, !,
1358+ create {create L X D RL} RV RD RR T.
1359+ bal.aux _ HR HL2 _ L X D (node (node RLL RLV RLD RLR _) RV RD RR _) T :-
1360+ HR > HL2, !,
1361+ create {create L X D RLL} RLV RLD {create RLR RV RD RR} T.
1362+ bal.aux _ _ _ _ L K V R T :- create L K V R T.
1363+
1364+ func add map K V, (func K, K -> cmp), K, V -> map K V.
1365+ add empty _ K V T :- create empty K V empty T.
1366+ add (node _ X _ _ _ as M) Cmp X1 XD M1 :- Cmp X1 X E, add.aux E M Cmp X1 XD M1.
1367+
1368+ func add.aux cmp, map K V, (func K, K -> cmp), K, V -> map K V.
1369+ add.aux eq (node L _ _ R H) _ X XD T :- unsound_unif T (node L X XD R H).
1370+ add.aux lt (node L V D R _) Cmp X XD T :- bal {add L Cmp X XD} V D R T.
1371+ add.aux gt (node L V D R _) Cmp X XD T :- bal L V D {add R Cmp X XD} T.
1372+
1373+ func find map K V, (func K, K -> cmp), K -> V.
1374+ find (node L K1 V1 R _) Cmp K V :- Cmp K K1 E, find.aux E Cmp L R V1 K V.
1375+
1376+ func find.aux cmp, (func K, K -> cmp), map K V, map K V, V, K -> V.
1377+ find.aux eq _ _ _ V _ V.
1378+ find.aux lt Cmp L _ _ K V :- find L Cmp K V.
1379+ find.aux gt Cmp _ R _ K V :- find R Cmp K V.
1380+
1381+ func remove-min-binding map K V -> map K V.
1382+ remove-min-binding (node empty _ _ R _) R :- !.
1383+ remove-min-binding (node L V D R _) X :- bal {remove-min-binding L} V D R X.
1384+
1385+ func min-binding map K V -> K, V.
1386+ min-binding (node empty V D _ _) V D :- !.
1387+ min-binding (node L _ _ _ _) V D :- min-binding L V D.
1388+
1389+ func merge map K V, map K V -> map K V.
1390+ merge empty X X :- !.
1391+ merge X empty X :- !.
1392+ merge M1 M2 R :-
1393+ min-binding M2 X D,
1394+ bal M1 X D {remove-min-binding M2} R.
1395+
1396+ func remove map K V, (func K, K -> cmp), K -> map K V.
1397+ remove empty _ _ empty :- !.
1398+ remove (node L V D R _) Cmp X M :- Cmp X V E, remove.aux E Cmp L R V D X M.
1399+
1400+ func remove.aux cmp, (func K, K -> cmp), map K V, map K V, K, V, K -> map K V.
1401+ remove.aux eq _ L R _ _ _ M :- merge L R M.
1402+ remove.aux lt Cmp L R V D X M :- bal {remove L Cmp X} V D R M.
1403+ remove.aux gt Cmp L R V D X M :- bal L V D {remove R Cmp X} M.
1404+
1405+ func bindings map K V, list (pair K V) -> list (pair K V).
1406+ bindings empty X X.
1407+ bindings (node L V D R _) X X1 :-
1408+ bindings L [pr V D|{bindings R X}] X1.
1409+
1410+
1411+ } % std.fmap.private
1412+ } % std.fmap
1413+
12791414
12801415#line 1 "builtin_set.elpi"
12811416kind std.set type -> type.
@@ -1396,6 +1531,139 @@ elements (node L E R _) Acc X :-
13961531} % std.set.private
13971532} % std.set
13981533
1534+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1535+
1536+ % Fast sets only work ground terms but do not perform occur check
1537+
1538+ kind std.fset type -> type.
1539+ type std.fset std.fset.private.set E -> (func E, E -> cmp) -> std.fset E.
1540+
1541+ namespace std.fset {
1542+
1543+ % [make Eq Ltn M] builds an empty set M where keys are compared using Eq and Ltn
1544+ func make (func E, E -> cmp) -> std.fset E.
1545+ make Cmp (std.fset private.empty Cmp).
1546+
1547+ % [mem E M] looks if E is in M
1548+ func mem E, std.fset E.
1549+ mem E (std.fset M Cmp):- private.mem M Cmp E.
1550+
1551+ % [add E M M1] M1 is M + {E}
1552+ func add E, std.fset E -> std.fset E.
1553+ add E (std.fset M Cmp) R :-
1554+ private.assert-ground E,
1555+ private.add M Cmp E M1,
1556+ unsound_unif R (std.fset M1 Cmp).
1557+
1558+ % [remove E M M1] M1 is M - {E}
1559+ func remove E, std.fset E -> std.fset E.
1560+ remove E (std.fset M Cmp) R :-
1561+ private.assert-ground E,
1562+ private.remove M Cmp E M1,
1563+ unsound_unif R (std.fset M1 Cmp).
1564+
1565+ % [cardinal S N] N is the number of elements of S
1566+ func cardinal std.fset E -> int.
1567+ cardinal (std.fset M _) N :- private.cardinal M N.
1568+
1569+ func elements std.fset E -> list E.
1570+ elements (std.fset M _) L :- private.elements M [] L.
1571+
1572+ namespace private {
1573+
1574+ func assert-ground A.
1575+ assert-ground A :- std.assert! (ground_term A) "std.fset: not ground".
1576+
1577+ % Taken from OCaml's set.ml
1578+ kind set type -> type.
1579+ type empty set E.
1580+ type node set E -> E -> set E -> int -> set E.
1581+
1582+ func height set E -> int.
1583+ height empty 0.
1584+ height (node _ _ _ H) H.
1585+
1586+ func create set E, E, set E -> set E.
1587+ create L E R S :-
1588+ H is {std.max {height L} {height R}} + 1,
1589+ unsound_unif S (node L E R H).
1590+
1591+ func bal set E, E, set E -> set E.
1592+ bal L E R T :-
1593+ height L HL,
1594+ height R HR,
1595+ HL2 is HL + 2,
1596+ HR2 is HR + 2,
1597+ bal.aux HL HR HL2 HR2 L E R T.
1598+
1599+ func bal.aux int, int, int, int, set E, E, set E -> set E.
1600+ bal.aux HL _ _ HR2 (node LL LV LR _) X R T :-
1601+ HL > HR2, {height LL} >= {height LR}, !,
1602+ create LL LV {create LR X R} T.
1603+ bal.aux HL _ _ HR2 (node LL LV (node LRL LRV LRR _) _) X R T :-
1604+ HL > HR2, !,
1605+ create {create LL LV LRL} LRV {create LRR X R} T.
1606+ bal.aux _ HR HL2 _ L X (node RL RV RR _) T :-
1607+ HR > HL2, {height RR} >= {height RL}, !,
1608+ create {create L X RL} RV RR T.
1609+ bal.aux _ HR HL2 _ L X (node (node RLL RLV RLR _) RV RR _) T :-
1610+ HR > HL2, !,
1611+ create {create L X RLL} RLV {create RLR RV RR} T.
1612+ bal.aux _ _ _ _ L E R T :- create L E R T.
1613+
1614+ func add set E, (func E, E -> cmp), E -> set E.
1615+ add empty _ E T :- create empty E empty T.
1616+ add (node L X R H) Cmp X1 S :- Cmp X1 X E, add.aux E Cmp L R X X1 H S.
1617+
1618+ func add.aux cmp, (func E, E -> cmp), set E, set E, E, E, int -> set E.
1619+ add.aux eq _ L R X _ H S :- unsound_unif S (node L X R H).
1620+ add.aux lt Cmp L R E X _ T :- bal {add L Cmp X} E R T.
1621+ add.aux gt Cmp L R E X _ T :- bal L E {add R Cmp X} T.
1622+
1623+ func mem set E, (func E, E -> cmp), E.
1624+ mem (node L K R _) Cmp E :- Cmp E K O, mem.aux O Cmp L R E.
1625+
1626+ func mem.aux cmp, (func E, E -> cmp), set E, set E, E.
1627+ mem.aux eq _ _ _ _.
1628+ mem.aux lt Cmp L _ E :- mem L Cmp E.
1629+ mem.aux gt Cmp _ R E :- mem R Cmp E.
1630+
1631+ func remove-min-binding set E -> set E.
1632+ remove-min-binding (node empty _ R _) R :- !.
1633+ remove-min-binding (node L E R _) X :- bal {remove-min-binding L} E R X.
1634+
1635+ func min-binding set E -> E.
1636+ min-binding (node empty E _ _) E :- !.
1637+ min-binding (node L _ _ _) E :- min-binding L E.
1638+
1639+ func merge set E, set E -> set E.
1640+ merge empty X X :- !.
1641+ merge X empty X :- !.
1642+ merge M1 M2 R :-
1643+ min-binding M2 X,
1644+ bal M1 X {remove-min-binding M2} R.
1645+
1646+ func remove set E, (func E, E -> cmp), E -> set E.
1647+ remove empty _ _ empty.
1648+ remove (node L E R _) Cmp X M :- Cmp X E O, remove.aux O Cmp L R E X M.
1649+
1650+ func remove.aux cmp, (func E, E -> cmp), set E, set E, E, E -> set E.
1651+ remove.aux eq _ L R _ _ M :- merge L R M.
1652+ remove.aux lt Cmp L R E X M :- bal {remove L Cmp X} E R M.
1653+ remove.aux gt Cmp L R E X M :- bal L E {remove R Cmp X} M.
1654+
1655+ func cardinal set E -> int.
1656+ cardinal empty 0.
1657+ cardinal (node L _ R _) N :- N is {cardinal L} + 1 + {cardinal R}.
1658+
1659+ func elements set E, list E -> list E.
1660+ elements empty X X.
1661+ elements (node L E R _) Acc X :-
1662+ elements L [E|{elements R Acc}] X.
1663+
1664+ } % std.fset.private
1665+ } % std.fset
1666+
13991667
14001668% == Elpi runtime builtins =====================================
14011669
0 commit comments