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