arXiv is now an independent nonprofit! Learn more
License: arXiv.org perpetual non-exclusive license
arXiv:2112.14603v4 [cs.AI] 15 May 2022

Learning Higher-Order Logic Programs From Failures         [Extended Version]

Authors contributed equally to the work described in this paper.Supported by the ERC starting grant no. 714034 SMART, the MathLP project (LIT-2019-7-YOU-213) of the Linz Institute of Technology and the state of Upper Austria, Cost action CA20111 EuroProofNet, and project CZ.02.2.69/0.0/0.0/18_053/0017594 of the Ministry of Education, Youth and Sports of the Czech Republic.
Stanisław J. Purgał Affiliation: University of Innsbruck, Innsbruck, Austria Email: stanislaw.purgal@uibk.ac.at    David M. Cerna Note: Contact Author Affiliation: Czech Academy of Sciences Institute of Computer Science (CAS ICS), Prague, Czechia Affiliation: Research Institute for Symbolic Computation (RISC), Johannes Kepler University, Linz, Austria Email: dcerna@{cs.cas.cz    Cezary Kaliszyk Affiliation: University of Innsbruck, Innsbruck, Austria Email:  risc.jku.at} Email: cezary.kaliszyk@uibk.ac.at
Abstract

Learning complex programs through inductive logic programming (ILP) remains a formidable challenge. Existing higher-order enabled ILP systems show improved accuracy and learning performance, though remain hampered by the limitations of the underlying learning mechanism. Experimental results show that our extension of the versatile Learning From Failures paradigm by higher-order definitions significantly improves learning performance without the burdensome human guidance required by existing systems. Our theoretical framework captures a class of higher-order definitions preserving soundness of existing subsumption-based pruning methods.

1 Introduction

Inductive Logic Programming, abbreviated ILP, Muggleton (1991); Nienhuys-Cheng et al. (1997) is a form of symbolic machine learning which learns a logic program from background knowledge (𝐵𝐾\mathit{BK}) predicates and sets of positive and negative example runs of the goal program.

Naively, learning a logic program which takes a positive integer nn and returns a list of list of the form [[1],[1,2]CLOSE,[[1],[1,2], OPEN,[1,,n]]\cdots,[1,\cdots,n]] would not come across as a formidable learning task. A logic program is easily constructed using conventional higher-order (HO) definitions.

𝚊𝚕𝚕𝚂𝚎𝚚𝙽(N,L)\displaystyle\mathtt{allSeqN}(N,L) :-𝚒𝚝𝚎𝚛𝚊𝚝𝚎(succ,0,N,A),𝚖𝚊𝚙(p,A,L).\displaystyle\mbox{:-}~\mathtt{iterate}(succ,0,N,A),\ \mathtt{map}(p,A,L).
𝚙(A,B)\displaystyle\mathtt{p}(A,B) :-𝚒𝚝𝚎𝚛𝚊𝚝𝚎(succ,0,A,B).\displaystyle\mbox{:-}~\mathtt{iterate}(succ,0,A,B).

The first 𝚒𝚝𝚎𝚛𝚊𝚝𝚎\mathtt{iterate}11 1 See Appendix of arXiv:2112.14603 for HO definitions. produces the list [1,,N][1,\cdots,N] and 𝚖𝚊𝚙\mathtt{map} applies a functionally equivalent 𝚒𝚝𝚎𝚛𝚊𝚝𝚎\mathtt{iterate} to each member of [1,,N][1,\cdots,N], thus producing the desired outcome. However, this seemingly innocuous function requires 25 literals spread over five clauses when written as a function-free, first-order (FO) logic program, a formidable task for most if not all existing FO ILP approaches Cropper et al. (2022).

Excessively large 𝐵𝐾\mathit{BK} can, in many cases, lead to performance loss Cropper (2020); Srinivasan et al. (2003). In contrast, adding HO definitions increases the overall size of the search space, but may result in the presence of significantly simpler solutions (see Figure 1). Enabling a learner, with a strong bias toward short solutions, with the ability to use HO definitions can result in improved performance. We developed an HO-enabled Popper Cropper and Morel (2021a) (Hopper), a novel ILP system designed to learn optimally short solutions. Experiments show significantly better performance on hard tasks when compared with Popper and the best performing HO-enabled ILP system, MetagolHO Cropper et al. (2020). See Section 4.

Refer to caption
Figure 1: Inclusion of HO definitions increases the size of the search space, but can lead to the search space containing a shorter solutions.

Existing HO-enabled ILP systems are based on Meta-inter-pretive Learning (MiL) Muggleton et al. (2014). The efficiency and performance of MiL-based systems is strongly dependent on significant human guidance in the form of metarules (a restricted form of HO horn clauses). Choosing these rules is an art in all but the simplest of cases. For example, 𝚒𝚝𝚎𝚛𝚊𝚝𝚎\mathtt{iterate}, being ternary (w.r.t. FO arguments), poses a challenge for some systems, and in the case of HEXMILHO Cropper et al. (2020), this definition cannot be considered as only binary definitions are allowed (w.r.t. FO arguments).

Limiting human participation when fine-tuning the search space is an essential step toward strong symbolic machine learning. The novel Learning from Failures (LFF) paradigm Cropper and Morel (2021a), realized through Popper, prunes the search space as part of the learning process. Not only does this decrease human guidance, but it also removes limitations on the structure of HO definitions allowing us to further exploit the above-mentioned benefits.

Integrating HO concepts into MiL-based systems is quite seamless as HO definitions are essentially a special type of metarule. Thus, HO enabling MiL learners requires minimal change to the theoretical foundations. In the case of LFF learners, like Popper, the pruning mechanism influences which HO definitions may be soundly used (See page 813 of Cropper and Morel (2021a)).

We avoid these soundness issues by indirectly adding HO definitions. Hopper  uses FO instances of HO definitions each of which is associated with a set of unique predicates symbols denoting the HO arguments of the definition. These predicates symbols occur in the head literal of clauses occurring in the candidate program iff their associated FO instance occurs in the candidate program. Thus, only programs with matching structure may be pruned. We further examine this issue in Section 3 and provide a construction encapsulating the accepted class of HO definitions.

Succinctly, we work within the class of HO definitions that are monotone with respect to subsumption and entailment; p1θ()p2H(p1)θ()H(p2)p_{1}\leq_{\theta}\hskip-4.49997pt(\models)\ p_{2}\Rightarrow H(p_{1})\leq_{\theta}\hskip-3.00003pt(\models)\ H(p_{2}) where p1p_{1} and p2p_{2} are logic programs, and H()H(\cdot) is an HO definition incorporating parts of p1p_{1} and p2p_{2}. Similar to classes considered in literature, our class excludes most cases of HO negation (see Section 3.4). However, our framework opens the opportunity to invent HO predicates during learning (an important open problem), though this remains too inefficient in practice and is left to future work.

2 Related Work

The authors of Cropper et al. (2020) (Section 2) provide a literature survey concerning the synthesis of Higher-Order (HO) programs and, in particular, how existing ILP systems deal with HO constructions. We provide a brief summary of this survey and focus on introducing the state-of-the-art systems, namely, HO extensions of Metagol Cropper and Muggleton (2016) and HEXMIL Kaminski et al. (2018). Also, we introduce Popper Cropper and Morel (2021a), the system Hopper is based on. For interested readers, a detailed survey of the current state of ILP research has recently been published Cropper et al. (2022).

2.1 Predicate Invention and HO Synthesis

Effective use of HO predicates is intimately connected to auxiliary Predicate Invention (PI). The following illustrates how fold/4 can be used together with PI to provide a succinct program for reversing a list:

𝚛𝚎𝚟𝚎𝚛𝚜𝚎(A,B)\displaystyle\mathtt{reverse}(A,B) :-𝚎𝚖𝚙𝚝𝚢(C),𝚏𝚘𝚕𝚍(p,C,A,B).\displaystyle\mbox{:-}~\mathtt{empty}(C),\ \mathtt{fold}(p,C,A,B).
𝚙(A,B,C)\displaystyle\mathtt{p}(A,B,C) :-𝚑𝚎𝚊𝚍(C,B),𝚝𝚊𝚒𝚕(C,A).\displaystyle\mbox{:-}~\mathtt{head}(C,B),\ \mathtt{tail}(C,A).

Including 𝚙\mathtt{p} in the background knowledge is unintuitive. It is reasonable to expect the synthesizer to produce it. Many of the well known, non-MiL based ILP frameworks do not support predicate invention, Foil Quinlan (1990), Progol Muggleton (1995), Tilde Blockeel (1999), and Aleph Srinivasan (2001) to name a few. While there has been much interest, throughout ILP’s long history, concerning PI, it remained an open problem discussed in “ILP turns 20” Muggleton et al. (2012). Since then, there have been a few successful approaches. Both ILASP Law et al. (2014) and δ\deltaILP Evans and Grefenstette (2018) can, in a restricted sense, introduce invented predicates, however, neither handles infinite domains nor are suited for the task we are investigating, manipulation of trees and lists.

The best-performing systems with respect to the aforementioned tasks are Metagol Cropper and Muggleton (2016) and HEXMIL Kaminski et al. (2018); both are based on Meta-interpretive Learning (MiL) Muggleton et al. (2014), where PI is considered at every step of program construction. However, a strong language bias is needed for an efficient search procedure. This language bias comes in the form of Metarules Cropper and Muggleton (2014), a restricted form of HO horn clauses.

Definition 1 (Cropper and Tourret (2020))

A metarule is a second-order Horn clause of the form A0A1,,AnA_{0}\leftarrow A_{1},\cdots,A_{n}, where AiA_{i} is a literal P(T1,,Tm)P(T_{1},\cdots,T_{m}), s.t. PP is either a predicate symbol or a HO variable and each TiT_{i} is either a constant or a FO variable.

For further discussion see Section 2.2. Popper Cropper and Morel (2021a), does not directly support PI, though, it is possible to enforce PI through the language bias (Poppi is an PI-enabled extension Cropper and Morel (2021b)) . Popper’s language bias, while partially fixed, is essentially an arbitrary ASP program. The authors of Cropper and Morel (2021a) illustrate this by providing ASP code emulating the chain metarule22 2 𝙿(A,B):-𝚀(A,C),𝚁(C,B).\mathtt{P}(A,B)\mbox{:-}~\mathtt{Q}(A,C),\mathtt{R}(C,B). (see Appendix A of Cropper and Morel (2021a)). We exploit this feature to extend Popper, allowing it to construct programs containing instances of HO definitions. Hopper, our extension, has drastically improved performance when compared with Popper. Hopper also outperforms the state-of-the-art MiL-based ILP systems extended by HO definitions. For further discussion of Popper see Section 2.3, and for Hopper see Section 3.

2.2 Metagol and HEXMIL

We briefly summarize existing HO-capable ILP systems introduced by A. Cropper et al. Cropper et al. (2020).

2.2.1 Higher-order Metagol

In short, Metagol is a MiL-learner implemented using a Prolog meta-interpreter. As input, Metagol takes a set of predicate declarations 𝑃𝐷\mathit{PD} of the form body_pred(P/n), sets of positive E+\mathit{E}^{+} and negative E\mathit{E}^{\mathrm{-}} examples, compiled background knowledge 𝐵𝐾c\mathit{BK}_{c}, and a set of metarules MM. The examples provide the arity and name of the goal predicate. Initially, Metagol attempts to satisfy E+\mathit{E}^{+} using 𝐵𝐾c\mathit{BK}_{c}. If this fails, then Metagol attempts to unify the current goal atom with a metarule from mMm\in M. At this point Metagol tries to prove the body of metarule mm. If successful, the derivation provides a Prolog program that can be tested on E\mathit{E}^{\mathrm{-}}. If the program entails some of E\mathit{E}^{\mathrm{-}}, Metagol backtracks and tries to find another program. Invented predicates are introduced while proving the body of a metarule when 𝐵𝐾c\mathit{BK}_{c} is not sufficient for the construction of a program.

The difference between Metagol and MetagolHO is the inclusion of interpreted background knowledge 𝐵𝐾in\mathit{BK}_{in}. For example, map/3 as 𝐵𝐾in\mathit{BK}_{in} takes the form:

ibk([map,[],[],_],[]).
ibk([map,[A|As],[B|Bs],F],[[F,A,B],[map,As,Bs,F]]).

Metagol handles 𝐵𝐾in\mathit{BK}_{in} as it handles metarules. When used, Metagol attempts to prove the body of map, i.e. F(A,B)F(A,B). Either FF is substituted by a predicate contained in 𝐵𝐾c\mathit{BK}_{c} or replaced by an invented predicate that becomes the goal atom and is proven using metarules or 𝐵𝐾in\mathit{BK}_{in}.

A consequence of this approach is that substituting the goal atom by a predicate defined as 𝐵𝐾in\mathit{BK}_{in} cannot result in a derivation defining a Prolog program. Like with metarules, additional proof steps are necessary. The following program defining 𝚑𝚊𝚕𝚏𝚕𝚜𝚝(A,B)\mathtt{half}_{\mathtt{lst}}(A,B), which computes the last half of a list33 3 𝚑𝚊𝚕𝚏𝚕𝚜𝚝([1,2],[2])\mathtt{half}_{\mathtt{lst}}([1,2],[2]), 𝚑𝚊𝚕𝚏𝚕𝚜𝚝([1,2,3],[3])\mathtt{half}_{\mathtt{lst}}([1,2,3],[3]), 𝚑𝚊𝚕𝚏𝚏𝚜𝚝([1,2,3],[1,2])\mathtt{half}_{\mathtt{fst}}([1,2,3],[1,2]). , illustrates why this may be problematic:

𝚑𝚊𝚕𝚏𝚕𝚜𝚝(A,B)\displaystyle\mathtt{half}_{\mathtt{lst}}(A,B) :-𝚛𝚎𝚟𝚎𝚛𝚜𝚎(A,C),\displaystyle\mbox{:-}~\mathtt{reverse}(A,C),
𝚌𝚊𝚜𝚎𝚕𝚒𝚜𝚝(p[],p[H|T],C,B).\displaystyle\ \ \ \ \ \mathtt{case}_{\mathtt{list}}(p_{\scriptscriptstyle[\ ]},p_{\scriptscriptstyle[H|T]},C,B).
𝚙[](A)\displaystyle\mathtt{p}_{\scriptscriptstyle[\ ]}(A) :-𝚎𝚖𝚙𝚝𝚢(A).\displaystyle\mbox{:-}~\mathtt{empty}(A).
𝚙[H|T](A,B,C)\displaystyle\mathtt{p}_{\scriptscriptstyle[H|T]}(A,B,C) :-𝚎𝚖𝚙𝚝𝚢(B),𝚎𝚖𝚙𝚝𝚢(C).\displaystyle\mbox{:-}~\mathtt{empty}(B),\mathtt{empty}(C).
𝚙[H|T](A,B,C)\displaystyle\mathtt{p}_{\scriptscriptstyle[H|T]}(A,B,C) :-𝚏𝚛𝚘𝚗𝚝(B,D),\displaystyle\mbox{:-}~\mathtt{front}(B,D),
𝚌𝚊𝚜𝚎𝚕𝚒𝚜𝚝(p[],p[H|T],D,E)¯,\displaystyle\ \ \ \ \ \underline{\mathtt{case}_{\mathtt{list}}(p_{\scriptscriptstyle[\ ]},p_{\scriptscriptstyle[H|T]},D,E)},
𝚊𝚙𝚙𝚎𝚗𝚍(E,A,C).\displaystyle\ \ \ \ \ \mathtt{append}(E,A,C).

The HO predicate 𝚌𝚊𝚜𝚎𝚕𝚒𝚜𝚝(p[],p[H|T],A,B)\mathtt{case}_{\mathtt{list}}(p_{\scriptscriptstyle[\ ]},p_{\scriptscriptstyle[H|T]},A,B) calls p[]p_{\scriptscriptstyle[\ ]} if AA is empty and p[H|T]p_{\scriptscriptstyle[H|T]} otherwise. Our definition of ℎ𝑎𝑙𝑓𝚕𝚜𝚝(A,B)\mathit{half}_{\mathtt{lst}}(A,B) cannot be found using the standard search procedure as every occurrence of 𝚌𝚊𝚜𝚎𝚕𝚒𝚜𝚝\mathtt{case}_{\mathtt{list}} results in a call to the meta-interpreter’s proof procedure. The underlined call to 𝚌𝚊𝚜𝚎𝚕𝚒𝚜𝚝\mathtt{case}_{\mathtt{list}} results in PI for 𝚙[H|T]\mathtt{p}_{\scriptscriptstyle[H|T]} ad infinitum. Similarly, the initial goal cannot be substituted unless it’s explicitly specified.

As with ℎ𝑎𝑙𝑓𝚕𝚜𝚝(A,B)\mathit{half}_{\mathtt{lst}}(A,B), The following program defining 𝚒𝚜𝚜𝚞𝚋𝚝𝚛𝚎𝚎(A,B)\mathtt{issubtree}(A,B), which computes whether BB is a subtree of AA, requires recursively calling 𝚒𝚜𝚜𝚞𝚋𝚝𝚛𝚎𝚎\mathtt{issubtree} through 𝚊𝚗𝚢\mathtt{any}.

𝚒𝚜𝚜𝚞𝚋𝚝𝚛𝚎𝚎(A,B)\displaystyle\mathtt{issubtree}(A,B) :-A=B.\displaystyle\mbox{:-}~A=B.
𝚒𝚜𝚜𝚞𝚋𝚝𝚛𝚎𝚎(A,B)\displaystyle\mathtt{issubtree}(A,B) :-𝚌𝚑𝚒𝚕𝚍𝚛𝚎𝚗(A,C),𝚊𝚗𝚢(𝚌𝚘𝚗𝚍,C,B).\displaystyle\mbox{:-}~\mathtt{children}(A,C),\mathtt{any}(\mathtt{cond},C,B).
𝚌𝚘𝚗𝚍(A,B)\displaystyle\mathtt{cond}(A,B) :-𝚒𝚜𝚜𝚞𝚋𝚝𝚛𝚎𝚎(A,B)¯.\displaystyle\mbox{:-}~\underline{\mathtt{issubtree}(A,B)}.

This can be resolved using metatypes (see Section 4), but this is non-standard, results in a strong language bias, and does not always work. Hopper successfully learns these predicates without any significant drawbacks.

Negation of invented predicates (HO arguments of 𝐵𝐾in\mathit{BK}_{in} definitions), to the best of our knowledge, is not fully supported by MetagolHO (See Section 4.2 of Cropper et al. (2020)). Hopper has similar issues which are discussed in Section 3.4.

2.2.2 Higher-order HEXMIL

HEXMIL is an ASP encoding of Meta-interpretive Learning Kaminski et al. (2018). Given that ASP can be quite restrictive, HEXMIL exploits the HEX formalism for encoding MiL. HEX allows the ASP solver to interface with external resources Eiter et al. (2016). HEXMIL is restricted to forward-chained metarules:

Definition 2

Forward-chained metarules are of the form: P(A,B):-Q1(A,C1),Q2(C1,C2),,Qn(Cn1,B),R1(P(A,B)\ \mbox{:-}\ Q_{1}(A,C_{1}),Q_{2}(C_{1},C_{2}),\cdots,Q_{n}(C_{n-1},B),R_{1}( 𝑂𝑃𝐸𝑁D1),,Rm(Dm)D_{1}),\cdots,R_{m}(D_{m}) where Di{A,C1,,Cn1,B}D_{i}\in\{A,C_{1},\cdots,C_{n-1},B\}.

Thus, only Dyadic learning task may be handled. Furthermore, many useful metarules are not of this form, i.e. P(A,B):-Q(A,B),R(A,B)P(A,B)\mbox{:-}~Q(A,B),R(A,B). HEXMILHO, incorporates HO definitions into the forward-chained structure of Definition 2. For details concerning the encoding see Section 4.4 of Cropper et al. (2020). The authors of Cropper et al. (2020) illustrated HEXMILHO’s poor performance on list manipulation tasks and its limitations make application to tasks of interest difficult. Thus, we focus on MetagolHO in Section 4.

2.3 Popper: Learning From Failures (LFF)

The LFF paradigm together with Popper provides a novel approach to inductive logic programming, based on counterexample guided inductive synthesis (CEGIS) Solar-Lezama (2008). Both LFF and the system implementing it were introduced by A. Cropper and R. Morel Cropper and Morel (2021a). As input, Popper takes a set of predicate declarations 𝑃𝐷\mathit{PD}, sets of positive E+\mathit{E}^{+} and negative E\mathit{E}^{\mathrm{-}} examples, and background knowledge 𝐵𝐾\mathit{BK}, the typical setting for learning from entailment ILP Raedt (2008).

During the generate phase, candidate programs are chosen from the viable hypothesis space, i.e. the space of programs that have yet to be ruled out by generated constraints. The chosen program is then tested (test phase) against E+\mathit{E}^{+} and E\mathit{E}^{\mathrm{-}}. If only some of E+\mathit{E}^{+} and/or some of E\mathit{E}^{\mathrm{-}} is entailed by the candidate hypothesis, Popper builds constraints (constrain phase) which further restrict the viable hypothesis space searched during the generate phase. When a candidate program only entails E+\mathit{E}^{+}, Popper terminates.

Popper searches through a finite hypothesis space, parameterized by features of the language bias (i.e. number of body predicates, variables, etc.). Importantly, if an optimal solution is present in this parameterized hypothesis space, Popper will find it (Theorem 1l Cropper and Morel (2021a)). Optimal is defined as the solution containing the fewest literals Cropper and Morel (2021a).

An essential aspect of this generate, test, constrain loop is the choice of constraints. Depending on how a candidate program performs in the test phase, Popper introduces constraints pruning specializations and/or generalizations of the candidate program. Specialization/generalization is defined via Θ\Theta-subsumption Plotkin (1970); Reynolds (1970). Popper may also introduce elimination Constraints pruning separable55 5 No head literal of a clause in the set occurs as a body literal of a clause in the set. sets of clauses. Details concerning the benefits of this approach are presented in Cropper and Morel (2021a). Essentially, Popper refines the hypothesis space, not the program Srinivasan (2001); Muggleton (1995); Quinlan and Cameron-Jones (1993).

In addition to constraints introduced during the search, like the majority of ILP systems, Popper incorporates a form of language bias Nienhuys-Cheng et al. (1997), that is predefined syntactic and/or semantic restrictions of the hypothesis space. Popper minimally requires predicate declarations, i.e. whether a predicate can be used in the head or body of a clause, and with what arities the predicate may appear. Popper accepts mode declaration-like hypothesis constraints Muggleton (1995) which declare, for each argument of a given predicate, the type, and direction. Additional hypothesis constraints can be formulated as ASP programs (mentioned in Section 2.1).

Popper implements the generate, test, constrain loop using a multi-shot solving framework Gebser et al. (2019) and an encoding of both definite logic programs and constraints within the ASP Lifschitz (2019) paradigm. The language bias together with the generated constraints is encoded as an ASP program. The ASP solver is run on this program and the resulting model (if one exists) is an encoding of a candidate program.

3 Theoretical Framework

We provide a brief overview of logic programming. Our exposition is far from comprehensive. We refer the interested reader to a more detailed source Lloyd (1987).

3.1 Preliminaries

Let 𝒫\mathcal{P} be a countable set of predicate symbols (denoted by p,q,r,p1,q1,p,q,r,p_{1},q_{1},\cdots), 𝒱f\mathcal{V}_{f} be a countable set of first-order (FO) variables (denoted by A,B,C,A,B,C,\cdots) , and 𝒱h\mathcal{V}_{h} be a countable set of HO variables (denoted by P,Q,R,P,Q,R,\cdots). Let 𝒯\mathcal{T} denote the set of FO terms constructed from a finite set of function symbols and 𝒱f\mathcal{V}_{f} (denoted by s,t,s1,t1,s,t,s_{1},t_{1},\cdots).

An atom is of the form p(T1,,Tm,t1,,tn)p(T_{1},\cdots,T_{m},t_{1},\cdots,t_{n}). Let us denote this atom by aa, then 𝑠𝑦(a)=p\mathit{sy}(a)=p is the symbol of the atom, 𝑎𝑔h(a)={T1,,Tm}\mathit{ag}_{\scriptscriptstyle h}(a)=\{T_{1},\cdots,T_{m}\} are its HO-arguments, and 𝑎𝑔f(a)={t1,,tn}\mathit{ag}_{\scriptscriptstyle f}(a)=\{t_{1},\cdots,t_{n}\} are its FO-arguments. When 𝑎𝑔h(a)=\mathit{ag}_{\scriptscriptstyle h}(a)=\emptyset and 𝑠𝑦(a)𝒫\mathit{sy}(a)\in\mathcal{P} we refer to aa as FO, when 𝑎𝑔h(a)𝒫\mathit{ag}_{\scriptscriptstyle h}(a)\subset\mathcal{P} and 𝑠𝑦(a)𝒫\mathit{sy}(a)\in\mathcal{P} we refer to aa as HO-ground, otherwise it is HO. A literal is either an atom or its negation. A literal is HO if the atom it contains is HO. 66 6 𝑠𝑦(l)\mathit{sy}(l), 𝑎𝑔h(l)\mathit{ag}_{\scriptscriptstyle h}(l), and 𝑎𝑔f(l)\mathit{ag}_{\scriptscriptstyle f}(l) apply to literals with similar affect.

A clause is a set of literals. A Horn clause contains at most one positive literal while a definite clause must have exactly one positive literal. The atom of the positive literal of a definite clause cc is referred to as the head of cc (denoted by ℎ𝑑(c)\mathit{hd}(c)), while the set of atoms of negated literals is referred to as the body (denoted by 𝑏𝑑(c)\mathit{bd}(c)). A function-free definite (f.f.d) clause only contains variables as FO arguments. We refer to a finite set of clauses as a theory. A theory is considered FO if all atoms are FO.

Replacing variables P1,,Pn,A1,,AmP_{1},\cdots,P_{n},A_{1},\cdots,A_{m} by predicate symbols p1,,pnp_{1},\cdots,p_{n} and terms t1,,tmt_{1},\cdots,t_{m} is a substitution (denoted by θ,σ,\theta,\sigma,\cdots) {P1p1,,Pnpn,A1t1,,Amtm}\{P_{1}\mapsto p_{1},\cdots,P_{n}\mapsto p_{n},A_{1}\mapsto t_{1},\cdots,A_{m}\mapsto t_{m}\}. A substitution θ\theta unifies two atoms when aθ=bθa\theta=b\theta.

3.2 Interpretable Theories and Groundings

Our hypothesis space consists of a particular type of theory which we refer to as interpretable. From these theories, one can derive so-called, principle programs, FO clausal theories encoding the relationship between certain literals and clauses and a set of higher-order definitions. Hopper  generates and tests principal programs. This encoding preserves the soundness of the pruning mechanism presented in Cropper and Morel (2021a). Intuitively, the soundness follows from each principal program encoding a unique HO program. A consequence of this approach is that each HO program may be encoded by multiple principal programs, some of which may not be in a subsumption relation to each other, i.e. not mutually prunable. This results in a larger, though more expressive hypothesis space.

Definition 3

A clause cc is proper77 7 Similar to definitional HO of W. Wadge Wadge (1991). if 𝑎𝑔h(ℎ𝑑(c))\mathit{ag}_{\scriptscriptstyle h}(\mathit{hd}(c)) are pairwise distinct, 𝑎𝑔h(ℎ𝑑(c))𝒱h\mathit{ag}_{\scriptscriptstyle h}(\mathit{hd}(c))\subset\mathcal{V}_{h}, and a𝑏𝑑(c)\forall a\in\mathit{bd}(c),

  • a)

    if 𝑠𝑦(a)𝒱h\mathit{sy}(a)\in\mathcal{V}_{h}, then 𝑠𝑦(a)𝑎𝑔h(ℎ𝑑(c))\mathit{sy}(a)\in\mathit{ag}_{\scriptscriptstyle h}(\mathit{hd}(c)), and

  • b)

    if p𝑎𝑔h(a)p\in\mathit{ag}_{\scriptscriptstyle h}(a) and p𝒱hp\in\mathcal{V}_{h}, then p𝑎𝑔h(ℎ𝑑(c))p\in\mathit{ag}_{\scriptscriptstyle h}(\mathit{hd}(c)).

A finite set of proper clauses dd with the same head (denoted ℎ𝑑(d)\mathit{hd}(d)) is referred to as a HO definition. A set of distinct HO definitions is a library. Let 𝒫PI𝒫\mathcal{P}_{PI}\subset\mathcal{P} be a set of predicate symbols reserved for invented predicates.

Definition 4

A f.f.d theory 𝔗\mathfrak{T} is interpretable if c𝔗\forall c\in\mathfrak{T}, 𝑎𝑔h(ℎ𝑑(c))=\mathit{ag}_{\scriptscriptstyle h}(\mathit{hd}(c))=\emptyset and l𝑏𝑑(c)\forall l\in\mathit{bd}(c), l is higher-order ground,

  • a)

    if 𝑎𝑔h(l)\mathit{ag}_{\scriptscriptstyle h}(l)\not=\emptyset, then c𝔗\forall c^{\prime}\in\mathfrak{T}, 𝑠𝑦(ℎ𝑑(c))𝑠𝑦(l)\mathit{sy}(\mathit{hd}(c^{\prime}))\not=\mathit{sy}(l), and

  • b)

    p𝑎𝑔h(l),c𝔗,\forall p\in\mathit{ag}_{\scriptscriptstyle h}(l),\exists c^{\prime}\in\mathfrak{T}, s.t. 𝑠𝑦(ℎ𝑑(c))=p𝒫PI.\mathit{sy}(\mathit{hd}(c^{\prime}))=p\in\mathcal{P}_{PI}.

Atoms s.t. 𝑎𝑔h(l)\mathit{ag}_{\scriptscriptstyle h}(l)\not=\emptyset are external. The set of external atoms of an interpretable theory 𝔗\mathfrak{T} is denoted by 𝑒𝑥(𝔗)\mathit{ex}(\mathfrak{T}).

Let SPI(𝔗)={pi|pi𝑎𝑔h(a)a𝑒𝑥(𝔗)}S_{PI}(\mathfrak{T})=\{p_{i}\ |\ p_{i}\in\mathit{ag}_{\scriptscriptstyle h}(a)\wedge a\in\mathit{ex}(\mathfrak{T})\}, the set of predicates which need to be invented. During the generate phase we enforce invention of SPI(𝔗)S_{PI}(\mathfrak{T}) by pruning programs which contain external literals, but do not contain clauses for their arguments. We discuss this in more detail in Section 3.3.1.

Otherwise, interpretable theories do not require significant adaption of Popper’s generate, test, constrain loop Cropper and Morel (2021a). The HO arguments of external literals are ignored by the ASP solver, which searches for so-called principal programs (an FO representation of interpretable theories).

Example 1

Consider 𝚛𝚎𝚟𝚎𝚛𝚜𝚎\mathtt{reverse}, 𝚑𝚊𝚕𝚏𝚕𝚜𝚝\mathtt{half}_{\mathtt{lst}}, and 𝚒𝚜𝚜𝚞𝚋𝚝𝚛𝚎𝚎\mathtt{issubtree} of Section 2.1 & 2.2. Each is an interpretable theory. The sets of external literals of these theories are {𝚏𝚘𝚕𝚍(p,C,A,B)}\{\mathtt{fold}(p,C,A,B)\}, {𝚌𝚊𝚜𝚎𝚕𝚒𝚜𝚝(p[],p[H|T],C,B),𝚌𝚊𝚜𝚎𝚕𝚒𝚜𝚝(p[],p[H|T],D,E)}\{\mathtt{case}_{\mathtt{list}}(p_{\scriptscriptstyle[\ ]},p_{\scriptscriptstyle[H|T]},C,B),\mathtt{case}_{\mathtt{list}}(p_{\scriptscriptstyle[\ ]},p_{\scriptscriptstyle[H|T]},D,E)\},
and {𝚊𝚗𝚢(𝚌𝚘𝚗𝚍,C,B)}\{\mathtt{any}(\mathtt{cond},C,B)\}, respectively.

Definition 5

Let LL be a library, and 𝔗\mathfrak{T} an interpretable theory. 𝔗\mathfrak{T} is LL-compatible if l𝑒𝑥(𝔗),!dL\forall l\in\mathit{ex}(\mathfrak{T}),\exists!d\in L. s.t. ℎ𝑑(d)σ=l\mathit{hd}(d)\sigma=l for some substitution σ\sigma. Let 𝑑𝑓(L,l)=d\mathit{df}(L,l)=d and θ(L,l)=σ\theta(L,l)=\sigma.

Example 2

The program in Section 2.1 is LL-compatible with the following library L=L=

𝚏𝚘𝚕𝚍(P,A,B,C)\displaystyle\mathtt{fold}(P,A,B,C) :-𝚎𝚖𝚙𝚝𝚢(B),C=A.\displaystyle\mbox{:-}~\mathtt{empty}(B),C\ =\ A.
𝚏𝚘𝚕𝚍(P,A,B,C)\displaystyle\mathtt{fold}(P,A,B,C) :-𝚑𝚎𝚊𝚍(B,H),𝙿(A,H,D),\displaystyle\mbox{:-}~\mathtt{head}(B,H),\mathtt{P}(A,H,D),
𝚝𝚊𝚒𝚕(B,T),𝚏𝚘𝚕𝚍(P,D,T,C).\displaystyle\ \ \ \ \ \mathtt{tail}(B,T),\mathtt{fold}(P,D,T,C).

Let l=fold(p,C,A,B)l=fold(p,C,A,B): 𝑑𝑓(L,l)=𝚏𝚘𝚕𝚍(P,A,B,C)\mathit{df}(L,l)=\mathtt{fold}(P,A,B,C) and θ(L,l)={Pp,AC,BA,CB}\theta(L,l)=\{P\mapsto p,A\mapsto C,B\mapsto A,C\mapsto B\}.

An LL-compatible theory 𝔗\mathfrak{T} can be LL-grounded. This requires replacing external literals of 𝔗\mathfrak{T} by FO literals, i.e. removal of all HO arguments and replacing the predicate symbol of the external literals with fresh predicate symbols, resulting in 𝔗\mathfrak{T}^{*}, and adding clauses that associate the FO literals ll with the appropriate dLd\in L and argument instantiations. different occurrences of external literals with the same symbol and same HO arguments result in FO literals with the same predicate symbol. The principal program contains all clauses derived from 𝔗\mathfrak{T}, i.e. 𝔗\mathfrak{T}^{*} (See Example 3).

Example 3

Using the library of Example 2 and a modified version of the program from Section 2.1 (pp is replaced by 𝚏𝚘𝚕𝚍p_a\mathtt{fold}_{p\_a} for clarity purposes), we get the following LL-grounding:

𝚛𝚎𝚟𝚎𝚛𝚜𝚎(A,B)\displaystyle\mathtt{reverse}(A,B) :-𝚎𝚖𝚙𝚝𝚢(C),𝚏𝚘𝚕𝚍a(C,A,B).\displaystyle\mbox{:-}~\mathtt{empty}(C),\ \mathtt{fold}_{a}(C,A,B).
𝚏𝚘𝚕𝚍p_a(A,B,C)\displaystyle\mathtt{fold}_{p\_a}(A,B,C) :-𝚑𝚎𝚊𝚍(C,B),𝚝𝚊𝚒𝚕(C,A).\displaystyle\mbox{:-}~\mathtt{head}(C,B),\ \mathtt{tail}(C,A).
𝚏𝚘𝚕𝚍a(A,B,C)\displaystyle\mathtt{fold}_{a}(A,B,C) :-𝚏𝚘𝚕𝚍(𝚏𝚘𝚕𝚍p_a,A,B,C).\displaystyle\mbox{:-}~\mathtt{fold}(\mathtt{fold}_{p\_a},A,B,C).
𝚏𝚘𝚕𝚍(P,A,B,C)\displaystyle\mathtt{fold}(P,A,B,C) :-𝚎𝚖𝚙𝚝𝚢(B),A=C.\displaystyle\mbox{:-}~\mathtt{empty}(B),A=C.
𝚏𝚘𝚕𝚍(P,A,B,C)\displaystyle\mathtt{fold}(P,A,B,C) :-𝚑𝚎𝚊𝚍(B,H),P(H,D),\displaystyle\mbox{:-}~\mathtt{head}(B,H),P(H,D),
𝚝𝚊𝚒𝚕(B,T),𝚏𝚘𝚕𝚍(P,D,T,C).\displaystyle\ \ \ \ \ \mathtt{tail}(B,T),\mathtt{fold}(P,D,T,C).

𝚏𝚘𝚕𝚍a(C,A,B)\mathtt{fold}_{a}(C,A,B) replaces 𝚏𝚘𝚕𝚍(𝚏𝚘𝚕𝚍p_a,C,A,B)\mathtt{fold}(\mathtt{fold}_{p\_a},C,A,B). The first two clauses form the principal program.

If an LL-compatible theory contains multiple external literals whose symbol is fold, i.e. 𝚏𝚘𝚕𝚍(𝚏𝚘𝚕𝚍p_a,C,A,B)\mathtt{fold}(\mathtt{fold}_{p\_a},C,A,B) and 𝚏𝚘𝚕𝚍(𝚏𝚘𝚕𝚍p_a,D,E,R)\mathtt{fold}(\mathtt{fold}_{p\_a},D,E,R), both are renamed to 𝚏𝚘𝚕𝚍a\mathtt{fold}_{a}. However, if the higher-order arguments differ, i.e. 𝚏𝚘𝚕𝚍p_a\mathtt{fold}_{p\_a}, and 𝚏𝚘𝚕𝚍p_b\mathtt{fold}_{p\_b}, then they are renamed to 𝚏𝚘𝚕𝚍a\mathtt{fold}_{a} and 𝚏𝚘𝚕𝚍b\mathtt{fold}_{b}, and an additional clause 𝚏𝚘𝚕𝚍b(A,B,C):-𝚏𝚘𝚕𝚍(𝚏𝚘𝚕𝚍p_b,A,B,C)\mathtt{fold}_{b}(A,B,C)\mbox{:-}~\mathtt{fold}(\mathtt{fold}_{p\_b},A,B,C) would be added to the LL-grounding. When a definition takes more than one HO argument and arguments of instances partially overlap, duplicating clauses may be required during the construction of the LL-grounding. Soundness of the pruning mechanism is preserved because the FO literals uniquely depend on the arguments fed to HO definitions.

Note, the system requires the user to provide higher-order definitions, similar to MetagolHO. Additionally, these HO definitions may be of the form ho(P,Q,x,y):-P(Q,x,y)ho(P,Q,x,y)\mbox{:-}~P(Q,x,y), essentially a higher-order definition template. While allowed by the formalism, we have not thoroughly investigated such constructions. This amounts to the invention of HO definitions.

3.3 Interpretable Theories and Constraints

The constraints of Section 2.3 are based on Θ\Theta-subsumption:

Definition 6 (Θ\Theta-subsumption)

An FO theory T1T_{1} subsumes an FO theory T2T_{2}, denoted by T1θT2T_{1}\leq_{\theta}T_{2} iff, c2T2c1T1\forall c_{2}\in T_{2}\exists c_{1}\in T_{1} s.t. c1θc2c_{1}\leq_{\theta}c_{2}, where c1θc2c_{1}\leq_{\theta}c_{2} iff, θ\exists\theta s.t. c1θc2c_{1}\theta\subseteq c_{2}.

Importantly, the following property holds:

Proposition 1

if T1θT2T_{1}\leq_{\theta}T_{2}, then T1T2T_{1}\models T_{2}

The pruning ability of Popper’s Generalization and specialization constraints follows from Proposition 1.

Definition 7

An FO theory T1T_{1} is a generalization (specialization) of an FO theory T2T_{2} iff T1θT2T_{1}\leq_{\theta}T_{2} (T2θT1T_{2}\leq_{\theta}T_{1}).

Given a library LL and a space of LL-compatible theories, we can compare LL-groundings using Θ\Theta-subsumption and prune generalizations (specializations), based on the Test phase.

3.3.1 Groundings and Elimination Constraints

During the generate phase, elimination constraints prune separable programs (See Footnote 5). While LL-groundings are non-separable, and thus avoid pruning in the presence of elimination constraints, it is inefficient to query the ASP solver for LL-groundings. The ASP solver would have to know the library and how to include definitions. Furthermore, the library must be written in an ASP-friendly form Cropper and Morel (2021a). Instead we query the ASP solver for the principal program. The definitions from the library LL are treated as 𝐵𝐾\mathit{BK}. Consider Example 3, during the generate phase the ASP solver may return an encoding of the following clauses:

𝚛𝚎𝚟𝚎𝚛𝚜𝚎(A,B)\displaystyle\mathtt{reverse}(A,B) :-𝚎𝚖𝚙𝚝𝚢(C),𝚏𝚘𝚕𝚍(C,A,B).\displaystyle\mbox{:-}~\mathtt{empty}(C),\ \mathtt{fold}(C,A,B).
𝚙(A,B,C)\displaystyle\mathtt{p}(A,B,C) :-𝚑𝚎𝚊𝚍(C,B),𝚝𝚊𝚒𝚕(C,A).\displaystyle\mbox{:-}~\mathtt{head}(C,B),\ \mathtt{tail}(C,A).

During the test phase the rest of the LL-grounding is re-introduced. While this eliminates inefficiencies, the above program is now separable and may be pruned. To efficiently implement HO synthesis we relaxed the elimination constraint in the presence of a library. Instead, we introduce so-called call graph constraints defining the relationship between HO literals and auxiliary clauses. This is similar to the dependency graph introduced in Cropper and Morel (2021b).

3.4 Negation, Generalization, and Specialization

Negation (under classical semantics) of HO literals can interfere with Popper constraints. Consider the ILP task and candidate programs:

E+:\displaystyle\mathbf{\mathit{E}^{+}:} f(b).f(c).\displaystyle\ f(b).\quad f(c). 𝐄:\displaystyle\mathbf{E^{-}:} f(a).\displaystyle\ f(a).
𝐵𝐾:\displaystyle\mathbf{\mathit{BK}:} {p(a).p(b).q(a).q(c).}\displaystyle\ \left\{\begin{array}[]{cc}p(a).&p(b).\\ q(a).&q(c).\end{array}\right\} 𝐇𝐎:\displaystyle\mathbf{HO}: N(P,A):-¬P(A).\displaystyle\ N(P,A)\mbox{:-}~\neg\ P(A).

𝑝𝑟𝑜𝑔s\mathit{prog_{s}}

𝚏(A)\displaystyle\mathtt{f}(A) :-𝙽(p1,A).\displaystyle\mbox{:-}~\mathtt{N}(p_{1},A).
𝚙𝟷(A)\displaystyle\mathtt{p_{1}}(A) :-𝚙(A),𝚚(A).\displaystyle\mbox{:-}~\mathtt{p}(A),\ \mathtt{q}(A).

𝑝𝑟𝑜𝑔f\mathit{prog_{f}}

𝚏(A)\displaystyle\mathtt{f}(A) :-𝙽(p1,A).\displaystyle\mbox{:-}~\mathtt{N}(p_{1},A).
𝚙𝟷(A)\displaystyle\mathtt{p_{1}}(A) :-𝚙(A).\displaystyle\mbox{:-}~\mathtt{p}(A).

The optimal solution is 𝑝𝑟𝑜𝑔s\mathit{prog_{s}}, 𝑝𝑟𝑜𝑔f\mathit{prog_{f}} is an incorrect hypothesis which Hopper can generate prior to 𝑝𝑟𝑜𝑔s\mathit{prog_{s}}, and 𝑝𝑟𝑜𝑔fθ𝑝𝑟𝑜𝑔s\mathit{prog_{f}}\leq_{\theta}\mathit{prog_{s}}. Note, 𝑝𝑟𝑜𝑔f¬f(b)¬f(a)f(c)\mathit{prog_{f}}\models\neg f(b)\wedge\neg f(a)\wedge f(c), it does not entail all of E+\mathit{E}^{+}. We should generalize 𝑝𝑟𝑜𝑔f\mathit{prog_{f}} to find a solution, i.e. add literals to p1p_{1}. The introduced constraints Cropper and Morel (2021a) prune programs extending p1p_{1}, i.e. 𝑝𝑟𝑜𝑔s\mathit{prog_{s}}. Similar holds for specializations. Consider the ILP task and candidate programs:

E+:\displaystyle\mathbf{\mathit{E}^{+}:} f(a).f(b).\displaystyle\ f(a).\quad f(b). 𝐄:\displaystyle\mathbf{E^{-}:} f(c).f(d).\displaystyle\ f(c).\quad f(d).
𝐵𝐾:\displaystyle\mathbf{\mathit{BK}:} {p(d).q(c).}\displaystyle\ \left\{\begin{array}[]{cc}p(d).&q(c).\end{array}\right\} 𝐇𝐎:\displaystyle\mathbf{HO}: N(P,X):-¬P(X).\displaystyle\ N(P,X)\mbox{:-}~\neg\ P(X).

𝑝𝑟𝑜𝑔s\mathit{prog_{s}}

𝚏(A)\displaystyle\mathtt{f}(A) :-𝙽(p1,A).\displaystyle\mbox{:-}~\mathtt{N}(p_{1},A).
𝚙𝟷(A)\displaystyle\mathtt{p_{1}}(A) :-𝚙(A).\displaystyle\mbox{:-}~\mathtt{p}(A).
𝚙𝟷(A)\displaystyle\mathtt{p_{1}}(A) :-𝚚(A).\displaystyle\mbox{:-}~\mathtt{q}(A).

𝑝𝑟𝑜𝑔f\mathit{prog_{f}}

𝚏(A)\displaystyle\mathtt{f}(A) :-𝙽(p1,A).\displaystyle\mbox{:-}~\mathtt{N}(p_{1},A).
𝚙𝟷(A)\displaystyle\mathtt{p_{1}}(A) :-𝚙(A).\displaystyle\mbox{:-}~\mathtt{p}(A).

The optimal solution is 𝑝𝑟𝑜𝑔s\mathit{prog_{s}}, 𝑝𝑟𝑜𝑔f\mathit{prog_{f}} is an incorrect hypothesis which Hopper can generate prior to 𝑝𝑟𝑜𝑔s\mathit{prog_{s}}, and 𝑝𝑟𝑜𝑔sθ𝑝𝑟𝑜𝑔f\mathit{prog_{s}}\leq_{\theta}\mathit{prog_{f}}. Note, 𝑝𝑟𝑜𝑔ff(a)f(b)f(c)\mathit{prog_{f}}\models f(a)\wedge f(b)\wedge f(c), it entails some of E\mathit{E}^{\mathrm{-}}. We should specialize p1p_{1} to find a solution, i.e. add clauses to 𝑝𝑟𝑜𝑔f\mathit{prog_{f}}. The introduced constraints Cropper and Morel (2021a) prune programs that add clauses, i.e. 𝑝𝑟𝑜𝑔s\mathit{prog_{s}}.

Handling negation of invented predicates is feasible but non-trivial as it would require significant changes to the constraint construction procedure. We leave it to future work.

4 Experiments

Task Popper (Opt) #Literals PI? Hopper Hopper (Opt) #Literals HO-Predicates MetagolHO Metatypes?
Learning Programs by learning from Failures Cropper and Morel (2021a)
dropK 1.1s 7 no 0.5s 0.1s 4 iterate no no
allEven 0.2s 7 no 0.2s 0.1s 4 all yes no
findDup 0.25s 7 no -- 0.5s 10 caseList no yes
length 0.1s 7 no 0.2s 0.1s 5 fold yes no
member 0.1s 5 no 0.2s 0.1s 4 any yes no
sorted 65.0s 9 no 46.3s 0.4s 6 fold yes no
reverse 11.2s 8 no 7.7s 0.5s 6 fold yes no
Learning Higher-Order Logic Programs Cropper et al. (2020)
dropLast 300.0s 10 no 300s 2.9s 6 map yes no
encryption 300.0s 12 no 300s 1.2s 7 map yes no
Additional Tasks
repeatN 5.0s 7 no 0.6s 0.1s 5 iterate yes no
rotateN 300.0s 10 no 300s 2.6s 6 iterate yes no
allSeqN 300.0s 25 yes 300s 5.0s 9 iterate, map yes no
dropLastK 300.0s 17 yes 300s 37.7s 11 map no no
firstHalf 300.0s 14 yes 300s 0.2s 9 iterateStep yes no
lastHalf 300.0s 12 no 300s 155.2s 12 caseList no yes
of1And2 300.0s 13 no 300s 6.9s 13 try no no
isPalindrome 300.0s 11 no 157s 2.4s 9 condlist no yes
depth 300.0s 14 yes 300s 10.1s 8 fold yes yes
isBranch 300.0s 17 yes 300s 25.9s 12 caseTree, any no yes
isSubTree 2.9s 11 yes 1.0s 0.9s 7 any yes yes
addN 300.0s 15 yes 300s 1.4s 9 map, caseInt yes no
mulFromSuc 300.0s 19 yes 300s 1.2s 7 iterate yes no
Table 1: We ran Popper, Hopper, optimized Hopper , and MetagolHO on a single core with a timeout of 300 second. Times denote the average of 5 runs. Evaluation time for Popper and Hopper  was set to a thousandth of a second, sufficient time for all task involved.

A possible, albeit very weak, program synthesizer is an enumeration procedure that orders all possible programs constructible from the 𝐵𝐾\mathit{BK} by size, testing each until a solution is found. In Cropper and Morel (2021a), this procedure was referred to as Enumerate. Popper extends Enumerate by pruning the hypothesis space based on previously tested programs.

The pruning mechanism will never prune the shortest solution. Thus, the important question when evaluating Popper, and Hopper, is not if Popper will find a solution, nor is it a high-quality solution, but rather how long it takes Popper to find the solution. An extensive suite of experiments was presented in Cropper and Morel (2021a), illustrating that Popper  outperforms Enumerate and existing ILP systems.

One way to improve the performance of LFF-based ILP systems, like Popper, is to introduce techniques that shorten or simplify the solution. The authors of Cropper et al. (2020), in addition to introducing MetagolHO and HEXMILHO, provided a comprehensive suite of experiments illustrating that the addition of HO predicates can improve accuracy and, most importantly, reduce learning time. Reduction in learning times results from a reduction in the complexity/size of the solutions.

The experiments in Cropper and Morel (2021a) thoroughly cover scalability issues and learning performance on simple list transformation tasks, but do not cover performance on complex tasks with large solutions. The experiments presented in Cropper et al. (2020) illustrate performance gains when a HO library is used to solve many simple tasks and how the addition of HO predicates allows the synthesis of relatively complex predicates such as dropLast. When the solution is large Popper’s performance degrades significantly. When the solution requires complex interaction between predicates and clauses it becomes exceedingly difficult to find a set of metarules for MetagolHOwithout being overly descriptive or suffering from long learning times.

Our experiments illustrate that the combination of Popper and HO predicates Cropper et al. (2020) significantly improves Popper’s performance at learning complex programs. Similar to Cropper and Morel (2021a), we use predicate declarations, i.e. body_pred(head,2), type declarations, i.e. type(head,(list,element)), direction declarations, i.e. direction(head,(in,out)), and the parameters required by Popper’s search mechanism, max_varmax_body, and max_clauses.

We reevaluated 7 of the tasks presented in Cropper and Morel (2021a) and 2 presented in Cropper et al. (2020). Additionally, we added 8 list manipulation tasks, 3 tree manipulation tasks, and 2 arithmetic tasks (separated by type in Table 1). Our additional tasks are significantly harder than the tasks evaluated in previous work.

For each task, we guarantee that the optimal solution is present in the hypothesis space and record how long Popper and Hopper take to find it. We ran Popper using optimal settings and minimal 𝐵𝐾\mathit{BK}. In some cases, the tasks cannot be solved by Popper without Predicate Invention (See Column PI? of Table 1), i.e. a explanatory hypothesis which is both accurate and precise requires auxiliary concepts.

We ran Hopper in two modes, Column Hopper  concerns running Hopper with the same settings and a superset of the 𝐵𝐾\mathit{BK} used by Popper (minus constructions used to force invention), while Column Hopper (Opt) concerns running Hopper with optimal settings and minimal 𝐵𝐾\mathit{BK}. For Popper and Hopper, settings such as max_var significantly impact performance. Both systems search for the shortest program (by literal count) respecting the current constraints. Note, that hypothesizing a program with an additional clause w.r.t the previously generated programs requires increasing the literal count by at least two. Thus, the current search procedure avoids such hypotheses until all shorter programs have been pruned or tested. The parameters max_var and max_body have a significant impact on the size of the single clause hypothesis space. Given that the use of HO definitions always requires auxiliary clauses, using large values, for the above-mentioned parameter, will hinder their use. This is why Hopper performs significantly better post-optimization. Using a comparably large 𝐵𝐾\mathit{BK} incurs an insignificant performance impact compared to using unintuitively large parameter settings (see Proposition 1, page 14 Cropper and Morel (2021a)).

The predicates used for a particular task are listed in Column HO-Predicate of Table 1. Popper and Hopper timed out (300 seconds elapsed) when large clauses or many variables are required. Timing out means the optimal solution was not found in 300 seconds. Given that we know the solution to each task, Column #Literals provides the size of the known solution, not the size of the non-optimal solution found by the system in case of timeout.

Concerning the Optimizations, these runs of Hopper closely emulate how such a system would be used as it is pragmatic to search assuming smaller clauses and fewer variables are sufficient and expand the space as needed. Popper’s and Hopper’s performance degrades by just assuming the solution may be complex. For findDup, Hopper found the FO solution.

Overall, this optimization issue raises a question concerning the search mechanism currently used by both Popper and Hopper. While HO solutions are typically shorter than the corresponding FO solution, this brevity comes at the cost of a complex program structure. This trade-off is not considered by the current implementations of the LFF paradigm. Investigating alternative search mechanisms and optimality conditions (other than literal count) is planned future work.

We attempted to solve each task using MetagolHO. Successful learning using MetagolHO is highly dependent on the choice of the metarules. To simplify matters, we chose metarules that mimic the clauses found in the solution. In some cases, this requires explicitly limiting how certain variables are instantiated by adding declarations, i.e. metagol:type(Q,2,head_pred), to the body of a metarule (denoted by metatype in Table 1). This amounts to significant human guidance, and thus, both simplifies learning and what we can say comparatively about the system. Hence we limit ourselves to indicating success or failure only.

Under these experimental settings, every successful task was solved faster by MetagolHO than Hopper with optimal settings. Relaxing restrictions on the metarule set introduces a new variable into the experiments. Choosing a set of metarules that is general and covers every task will likely result in the failure of the majority of tasks. Some tasks require splitting rules such as P(A,B):-Q(A,B),R(A,B)P(A,B)\mbox{:-}~Q(A,B),R(A,B) which significantly increase the size of the hypothesis space. Choosing metarules per task, but without optimizing for success, leaves the question, which metarules are appropriate/acceptable for the given task? While this is an interesting question Cropper and Tourret (2020), the existence problem of a set of general metarules over which MetagolHO’s performance is comparable to, or even better than, Hopper’s only strengthens our argument concerning the chosen experimental setting as one will have to deduce/design this set.

5 Conclusion and Future Work

We extended the LFF-based ILP system Popper to effectively use user-provided HO definitions during learning. Our experiments show Hopper (when optimized) is capable of outperforming Popper on most tasks, especially the harder tasks we introduced in this work (Section 4). Hopper requires minimal guidance compared to the top-performing MiL-based ILP system MetagolHO. Our experiments test the theoretical possibility of MetagolHO finding a solution under significant guidance. However, given the sensitivity to metarule choice and the fact that many tasks have ternary and even 4-ary predicates, it is hard to properly compare these approaches.

We provide a theoretical framework encapsulating the accepted HO definitions, a fragment of the definitions monotone over subsumption and entailment, and discuss the limitations of this framework. A detailed account is provided in Section 3. The main limitation of this framework concerns HO-negation which we leave to future work. Our framework also allows for the invention of HO predicates during learning through constructions of the form ho(P,Q,x,y):-P(Q,x,y)ho(P,Q,x,y)\mbox{:-}~P(Q,x,y). We can verify that Hopper can, in principal, finds the solution, but we have notsuccessfully invent an HO predicate during learning. We plan for further investigation of this problem.

As briefly mentioned, Hopper was tested twice during experimentation due to the significant impact system parameters have on its performance. This can be seen as an artifact of the current implementation of LFF which is bias towards programs with fewer, but longer, clauses rather than programs with many short clauses. An alternative implementation of LFF taking this bias into account, together with other bias, is left to future investigation.

Acknowledgements

We would like to thank Rolf Morel and Andrew Cropper for their thorough commentary which helped us greatly improve a preliminary version of this paper.

References

  • Blockeel [1999] Hendrik Blockeel. Top-down induction of first order logical decision trees. AI Communications, 12(1–2):119–120, January 1999.
  • Cropper and Morel [2021a] Andrew Cropper and Rolf Morel. Learning programs by learning from failures. Machine Learning, 110(4):801–856, February 2021.
  • Cropper and Morel [2021b] Andrew Cropper and Rolf Morel. Predicate invention by learning from failures. CoRR, abs/2104.14426, May 2021.
  • Cropper and Muggleton [2014] Andrew Cropper and Stephen H. Muggleton. Logical minimisation of metarules within meta-interpretive learning. In Proceedings of the 24th International Conference on Inductive Logic Programming, pages 62–75, Nancy, France, September 2014. Springer.
  • Cropper and Muggleton [2016] Andrew Cropper and Stephen Muggleton. Metagol system. github.com/metagol/metagol, 2016.
  • Cropper and Tourret [2020] Andrew Cropper and Sophie Tourret. Logical reduction of metarules. Machine Learning, 109(7):1323–1369, July 2020.
  • Cropper et al. [2020] Andrew Cropper, Rolf Morel, and Stephen Muggleton. Learning higher-order logic programs. Machine Learning, 109(7):1289–1322, July 2020.
  • Cropper et al. [2022] Andrew Cropper, Sebastijan Dumančić, Richard Evans, and Stephen H. Muggleton. Inductive logic programming at 30. Machine Learning, 111(1):147–172, Jan 2022.
  • Cropper [2020] Andrew Cropper. Forgetting to learn logic programs. Proceedings of the AAAI Conference on Artificial Intelligence, 34(04):3676–3683, April 2020.
  • Eiter et al. [2016] Thomas Eiter, Christoph Redl, and Peter Schüller. Problem solving using the HEX family. In Proceedings of Computational Models of Rationality, pages 150–174. College Publications, June 2016.
  • Evans and Grefenstette [2018] Richard Evans and Edward Grefenstette. Learning explanatory rules from noisy data. Journal of Artificial Intelligence Research, 61:1–64, January 2018.
  • Gebser et al. [2019] Martin Gebser, Roland Kaminski, Benjamin Kaufmann, and Torsten Schaub. Multi-shot asp solving with clingo. Theory and Practice of Logic Programming, 19(1):27–82, July 2019.
  • Kaminski et al. [2018] Tobias Kaminski, Thomas Eiter, and Katsumi Inoue. Exploiting answer set programming with external sources for meta-interpretive learning. Theory and Practice of Logic Programming, 18(3-4):571–588, October 2018.
  • Law et al. [2014] Mark Law, Alessandra Russo, and Krysia Broda. Inductive learning of answer set programs. In Proceedings of Logics in Artificial Intelligence, pages 311–325. Springer, August 2014.
  • Lifschitz [2019] Vladimir Lifschitz. Answer Set Programming. Springer, August 2019.
  • Lloyd [1987] John W. Lloyd. Foundations of Logic Programming, 2nd Edition. Springer, 1987.
  • Muggleton et al. [2012] Stephen Muggleton, Luc De Raedt, David Poole, Ivan Bratko, Peter A. Flach, Katsumi Inoue, and Ashwin Srinivasan. ILP turns 20 - biography and future challenges. Machince Learning, 86(1):3–23, January 2012.
  • Muggleton et al. [2014] Stephen H. Muggleton, Dianhuan Lin, Niels Pahlavi, and Alireza Tamaddoni-Nezhad. Meta-interpretive learning: application to grammatical inference. Machince Learning, 94(1):25–49, January 2014.
  • Muggleton [1991] Stephen Muggleton. Inductive logic programming. New Generation Computing, 8(4):295–318, February 1991.
  • Muggleton [1995] Stephen Muggleton. Inverse entailment and progol. New Generation Computing, 13(3&4):245–286, December 1995.
  • Nienhuys-Cheng et al. [1997] Shan-Hwei Nienhuys-Cheng, Ronald de Wolf, J. Siekmann, and J. G. Carbonell. Foundations of Inductive Logic Programming. Springer, 1997.
  • Plotkin [1970] Gordon D. Plotkin. A note on inductive generalization. Machine Intelligence, 5(1):153–163, 1970.
  • Quinlan and Cameron-Jones [1993] J. R. Quinlan and R. M. Cameron-Jones. Foil: A midterm report. In Proceedings of the European Conference on Machine Learning, pages 1–20, Vienna, Austria, April 1993. Springer.
  • Quinlan [1990] J. Ross Quinlan. Learning logical definitions from relations. Machine Learning, 5:239–266, August 1990.
  • Raedt [2008] Luc De Raedt. Logical and relational learning. Cognitive Technologies. Springer, 2008.
  • Reynolds [1970] John C. Reynolds. Transformational systems and the algebraic structure of atomic formulas. Machine Intelligence, 5(1):135–151, 1970.
  • Solar-Lezama [2008] Armando Solar-Lezama. Program Synthesis by Sketching. PhD thesis, University of California at Berkeley, USA, December 2008.
  • Srinivasan et al. [2003] Ashwin Srinivasan, Ross D. King, and Michael E. Bain. An empirical study of the use of relevance information in inductive logic programming. Journal of Machine Learning Research, 4:369–383, December 2003.
  • Srinivasan [2001] Ashwin Srinivasan. The ALEPH manual. Technical report, Machine Learning at the Computing Laboratory, Oxford University, 2001.
  • Wadge [1991] William W. Wadge. Higher-order horn logic programming. In Vijay A. Saraswat and Kazunori Ueda, editors, Proceedings of the International Symposium on Logic Programming, pages 289–303, San Diego, California, USA, October 1991. MIT Press.

Appendix A Implementation

We implement our method by building on top of code provided by Cropper and Morel [2021a]. The changes we applied include:

Processing HO predicates

We allow user to declare some background knowledge predicates to be HO. Based on these declarations we generate ASP constraints discussed in subsection 3.2 and Prolog code that allows execution of programs generated with those constraints.

Generating context-passing versions of HO predicates

Sometimes the HO argument predicates (referred to as SPI(𝔗)S_{PI}(\mathfrak{T}) in subsection 3.2) require context that exists in the predicate that calls them, however is inaccessible to them in our framework. To make it accessible we support automating generation of more contextual versions of HO predicates. These predicates have higher arity and take more FO arguments. These arguments are only used in HO calls, and are simply passed as arguments to HO predicate calls. In Cropper et al. [2020] this process is referred to as ,,currying“ (though it is somewhat different to what currying is usually considered to be).

Example 4

From a HO map predicate

𝚖𝚊𝚙(P,[],[])\displaystyle\mathtt{map}(P,[\ ],[\ ]) .
𝚖𝚊𝚙(P,[H1|T1],[H2|T2])\displaystyle\mathtt{map}(P,[H_{1}|T_{1}],[H_{2}|T_{2}]) :-P(H1,H2),𝚖𝚊𝚙(P,T1,T2).\displaystyle\mbox{:-}~P(H_{1},H_{2}),\mathtt{map}(P,T_{1},T_{2}).

we automatically generate a more contextual version

𝚖𝚊𝚙(P,[],[],V).\displaystyle\mathtt{map}(P,\mathtt{[\ ]},[\ ],V).\ \ \
𝚖𝚊𝚙(P,[H1|T1],[H2|T2],V):-\displaystyle\mathtt{map}(P,[H_{1}|T_{1}],[H_{2}|T_{2}],V)\mbox{:-}~ P(H1,H2,V),\displaystyle P(H_{1},H_{2},V),
𝚖𝚊𝚙(P,T1,T2,V).\displaystyle\mathtt{map}(P,T_{1},T_{2},V).

which allows for construction of a program that adds a number to every element of a list using map

𝚏(A,B,C):-\displaystyle\mathtt{f}(A,B,C)\mbox{:-}~ 𝚖𝚊𝚙(𝚙𝟷,B,C,A).\displaystyle\mathtt{map}(\mathtt{p_{1}},B,C,A).
𝚙𝟷(A,B,C):-\displaystyle\mathtt{p_{1}}(A,B,C)\mbox{:-}~ 𝚊𝚍𝚍(A,C,B).\displaystyle\mathtt{add}(A,C,B).
Force all generated code to be used

Since ASP can now generate many different predicates, some of them might not even be called in the main predicate. To avoid such useless code we make ASP keep track of a call graph – which predicates call which other predicates, and add a constraint that forces every defined defined predicate to be called (possibly indirectly) by the main predicate. This not only removes many variations of effectively the same program, but also significantly prunes the hypothesis space, pruning programs ignored by other constraints (explained in sec. 3.3.1).

Changes to separability and recursion

We add a few small changes to solve the problems that appear when generating multiple predicates. We make sure that clauses that call HO predicates (and thus different predicates from the program) are not considered separable. We also change how recursion is handled – otherwise recursion would allow all invented arguments to be called everywhere in the program, needlessly increasing search space.

Appendix B Experimental details

Here we describe all tasks and HO predicates presented in Section 4.

B.1 Higher-Order predicates

B.1.1 all/2

 

The argument predicate is true for all elements of the list

𝚊𝚕𝚕(P,[]).\displaystyle\mathtt{all}(P,[\ ]).\ \ \
𝚊𝚕𝚕(P,[H|T]):-\displaystyle\mathtt{all}(P,[H|T])\mbox{:-}~ call(P,H),𝚊𝚕𝚕(P,T).\displaystyle\texttt{call}(P,H),\mathtt{all}(P,T).

B.1.2 any/3

 

checks if for some element in a list and an input object if provided to a given predicate, then that predicate holds .

any(P,[H|_],B)\displaystyle\texttt{any}(P,[H|\_],B) :-call(P,H,B).\displaystyle\mbox{:-}~\texttt{call}(P,H,B).
any(P,[_|T],B)\displaystyle\texttt{any}(P,[\_|T],B) :-any(P,T,B).\displaystyle\mbox{:-}~\texttt{any}(P,T,B).

B.1.3 caseList/4

 

a deconstructor for a list, calling first or second predicate depending on whether the list is empty

caseList(P,_,[],B)\displaystyle\texttt{caseList}(P,\_,[],B) :-call(P,B).\displaystyle\mbox{:-}~\texttt{call}(P,B).
caseList(_,Q,[H|T],B)\displaystyle\texttt{caseList}(\_,Q,[H|T],B) :-call(Q,H,T,B).\displaystyle\mbox{:-}~\texttt{call}(Q,H,T,B).

B.1.4 caseList/5

 

a deconstructor for a list, calling the first, second, third predicate depending on whether the list is empty or singleton. Takes an additional argument which is passed to the predicate arguments.

caseList(P,_,_,[],B)\displaystyle\texttt{caseList}(P,\_,\_,[],B) :-call(P,B).\displaystyle\mbox{:-}~\texttt{call}(P,B).
caseList(_,Q,_,[H],B)\displaystyle\texttt{caseList}(\_,Q,\_,[H],B) :-call(Q,H,B).\displaystyle\mbox{:-}~\texttt{call}(Q,H,B).
caseList(_,_,R,[H|T],B)\displaystyle\texttt{caseList}(\_,\_,R,[H|T],B) :-call(R,H,T,B).\displaystyle\mbox{:-}~\texttt{call}(R,H,T,B).

B.1.5 caseTree/4

 

a deconstructor for a tree, calling first or second predicate depending on whether the tree is a leaf

casetree(P,_,t(R,[]),A)\displaystyle\texttt{casetree}(P,\_,t(R,[]),A) :-call(P,R,A).\displaystyle\mbox{:-}~\texttt{call}(P,R,A).
casetree(_,Q,t(R,[H|T]),A)\displaystyle\texttt{casetree}(\_,Q,t(R,[H|T]),A) :-call(Q,R,[H|T],A).\displaystyle\mbox{:-}~\texttt{call}(Q,R,[H|T],A).

B.1.6 caseInt/4

 

A deconstructor for a natural number, calling first or second predicate depending on whether the number  is  0.

caseint(P,_,0,X,Y)\displaystyle\texttt{caseint}(P,\_,0,X,Y) :-call(P,X,Y).\displaystyle\mbox{:-}~\texttt{call}(P,X,Y).
caseint(_,Q,N,B)\displaystyle\texttt{caseint}(\_,Q,N,B) :-less0(N),pred(N,M),\displaystyle\mbox{:-}~\texttt{less0}(N),\texttt{pred}(N,M),
call(Q,M,X,Y).\displaystyle\ \ \ \texttt{call}(Q,M,X,Y).

B.1.7 fold/4

 

combines all elements of a list using the argument predicate.

fold(_,X,[],X).\displaystyle\texttt{fold}(\_,X,[],X).
fold(P,Acc,[H|T],Y)\displaystyle\texttt{fold}(P,Acc,[H|T],Y) :-call(P,Acc,H,W),\displaystyle\mbox{:-}~\texttt{call}(P,Acc,H,W),
fold(P,W,T,Y).\displaystyle\ \ \ \texttt{fold}(P,W,T,Y).

B.1.8 map/3

 

checks that the output is a list of the same length as input, such that the argument predicate holds between all their elements.

𝚖𝚊𝚙(P,[],[])\displaystyle\mathtt{map}(P,[\ ],[\ ]) .
𝚖𝚊𝚙(P,[H1|T1],[H2|T2])\displaystyle\mathtt{map}(P,[H_{1}|T_{1}],[H_{2}|T_{2}]) :-call(P,H1,H2),𝚖𝚊𝚙(P,T1,T2).\displaystyle\mbox{:-}~\texttt{call}(P,H_{1},H_{2}),\mathtt{map}(P,T_{1},T_{2}).

B.1.9 try/3

 

checks whether at least one of argument predicates hold on the last argument

try(P,_,X)\displaystyle\texttt{try}(P,\_,X) :-call(P,X).\displaystyle\mbox{:-}~\texttt{call}(P,X).
try(_,Q,X)\displaystyle\texttt{try}(\_,Q,X) :-call(Q,X).\displaystyle\mbox{:-}~\texttt{call}(Q,X).

B.1.10 condList/2

 

true if argument is an empty list, otherwise call argument predicate on the head and the tail.

condList(P,[]).\displaystyle\texttt{condList}(P,[]).
condList(P,[H|T])\displaystyle\texttt{condList}(P,[H|T]) :-call(P,H,T).\displaystyle\mbox{:-}~\texttt{call}(P,H,T).

B.1.11 iterate/4

 

iterate the argument predicate nn times

iterate(_,X,0,X).\displaystyle\texttt{iterate}(\_,X,0,X).
iterate(P,X,K,W)\displaystyle\texttt{iterate}(P,X,K,W) :-integer(K),0<K,!,\displaystyle\mbox{:-}~\texttt{integer}(K),0<K,!,
pred(K,R),\displaystyle\ \ \ \texttt{pred}(K,R),
call(P,X,H),\displaystyle\ \ \ \texttt{call}(P,X,H),
iterate(P,H,R,W).\displaystyle\ \ \ \texttt{iterate}(P,H,R,W).

B.1.12 iterateStep/5

 

A variant of iterate/4, but the iterator instead of being modified by 1 is modified using an argument predicate. Also the output here is a list of all intermediate values.

iterate(_,_,_,0,[]).\displaystyle\texttt{iterate}(\_,\_,\_,0,[]).
iterate(P,Q,X,K,[H|T])\displaystyle\texttt{iterate}(P,Q,X,K,[H|T]) :-integer(K)\displaystyle\mbox{:-}~\texttt{integer}(K)
call(P,K,R),\displaystyle\ \ \ \texttt{call}(P,K,R),
call(Q,X,H,W),\displaystyle\ \ \ \texttt{call}(Q,X,H,W),
iterate(P,Q,W,R,T).\displaystyle\ \ \ \texttt{iterate}(P,Q,W,R,T).

Appendix C Learning tasks

In this section we provide the experimental set up for all learning task discussed above. For each task we provide the following information:

  • FO Background: 𝐵𝐾\mathit{BK}  used for the first order learning task.

  • FO Parameters: The values for the essential parameters of Popper  and any switches which where enabled during FO learning.

  • FO Solution: The solution found by Popper  or the solution we expected Popper  to find if given enough time.

  • HO Optimal Background: 𝐵𝐾\mathit{BK}  used for the Higher order learning task when ran in the optimal configuration. When ran in the non-optimal configuration we used the union of the FO 𝐵𝐾\mathit{BK}  with the HO optimal 𝐵𝐾\mathit{BK}  minus any HO predicates used for predicate invention during FO learning.

  • HO Optimal Parameters: The values for the essential parameters of Hopper  and any switches which where enabled during HO optimal learning. In the non-optimal case we used the setting of the first order learning task minus switches activated specifically for predicate invention during the first order task.

  • HO Solution: The solution found by Hopper  or the solution we expected Hopper  to find if given enough time.

C.1 dropK/3

 

drop first kk elements from a list

  • FO Background: suc, pred, zero, tail, head, eq

  • FO Parameters:

    • max_vars: 5

    • max_body: 3

    • max_clause: 2

    • Switches: enable_recursion

  • FO Solution:

    dropK(A,B,C)\displaystyle\texttt{dropK}(A,B,C) :-zero(A),eq(B,C).\displaystyle\mbox{:-}~\texttt{zero}(A),\texttt{eq}(B,C).
    dropK(A,B,C)\displaystyle\texttt{dropK}(A,B,C) :-tail(B,D),pred(A,E),dropK(E,D,C).\displaystyle\mbox{:-}~\texttt{tail}(B,D),\texttt{pred}(A,E),\texttt{dropK}(E,D,C).
  • HO Optimal Background: suc, zero, tail, head

  • HO Optimal Parameters:

    • max_vars: 3

    • max_body: 2

    • max_clause: 2

    • Switches:

  • HO Solution:

    dropK(A,B,C)\displaystyle\texttt{dropK}(A,B,C) :-iterate_a(B,A,C).\displaystyle\mbox{:-}~\texttt{iterate\_a}(B,A,C).
    iterate_p_a(A,B)\displaystyle\texttt{iterate\_p\_a}(A,B) :-tail(A,B).\displaystyle\mbox{:-}~\texttt{tail}(A,B).

C.2 allEven/1

 

check whether all elements on a list are even

  • FO Background: suc, zero, even, tail, head, empty

  • FO Parameters:

    • max_vars: 3

    • max_body: 4

    • max_clause: 2

    • Switches: enable_recursion

  • FO Solution:

    allEven(A)\displaystyle\texttt{allEven}(A) :-empty(A).\displaystyle\mbox{:-}~\texttt{empty}(A).
    allEven(A)\displaystyle\texttt{allEven}(A) :-head(A,B),even(B),\displaystyle\mbox{:-}~\texttt{head}(A,B),\texttt{even}(B),
    tail(A,C),allEven(C).\displaystyle\texttt{tail}(A,C),\texttt{allEven}(C).
  • HO Optimal Background: even, all

  • HO Optimal Parameters:

    • max_vars: 2

    • max_body: 2

    • max_clause: 2

    • Switches:

  • HO Solution:

    allEven(A)\displaystyle\texttt{allEven}(A) :-all_a(A).\displaystyle\mbox{:-}~\texttt{all\_a}(A).
    all_p_a(A)\displaystyle\texttt{all\_p\_a}(A) :-even(A).\displaystyle\mbox{:-}~\texttt{even}(A).

C.3 findDup/2

 

check whether an element is present on a list at least twice

  • FO Background: member, head, tail, empty

  • FO Parameters:

    • max_vars: 4

    • max_body: 4

    • max_clause: 2

    • Switches: enable_recursion

  • FO Solution:

    findDup(A,B)\displaystyle\texttt{findDup}(A,B) :-tail(A,C),empty(B,C),head(A,B).\displaystyle\mbox{:-}~\texttt{tail}(A,C),\texttt{empty}(B,C),\texttt{head}(A,B).
    findDup(A,B)\displaystyle\texttt{findDup}(A,B) :-tail(A,C),findDup(C,B).\displaystyle\mbox{:-}~\texttt{tail}(A,C),\texttt{findDup}(C,B).
  • HO Optimal Background: empty, eq, member

  • HO Optimal Parameters:

    • max_vars: 3

    • max_body: 2

    • max_clause: 4

    • Switches:non_datalog , allow_singletons

  • HO Solution:

    findDup(A,B)\displaystyle\texttt{findDup}(A,B) :-caseList_a(A,B).\displaystyle\mbox{:-}~\texttt{caseList\_a}(A,B).
    caseList_p_a(A)\displaystyle\texttt{caseList\_p\_a}(A) :-empty(B),member(A,B).\displaystyle\mbox{:-}~\texttt{empty}(B),\texttt{member}(A,B).
    caseList_q_a(A)\displaystyle\texttt{caseList\_q\_a}(A) :-member(C,B),eq(C,A).\displaystyle\mbox{:-}~\texttt{member}(C,B),\texttt{eq}(C,A).
    caseList_q_a(A)\displaystyle\texttt{caseList\_q\_a}(A) :-caseList_a(B,C).\displaystyle\mbox{:-}~\texttt{caseList\_a}(B,C).

C.4 length/2

 

Finds the length of a list.

  • FO Background: head, tail, succ, empty, zero.

  • FO Parameters:

    • max_vars: 4

    • max_body: 3

    • max_clause: 2

    • Switches: enable_recursion

  • FO Solution:

    length(A,B)\displaystyle\texttt{length}(A,B) :-empty(A),zero(B).\displaystyle\mbox{:-}~\texttt{empty}(A),\texttt{zero}(B).
    length(A,B)\displaystyle\texttt{length}(A,B) :-tail(A,C),length(C,D),\displaystyle\mbox{:-}~\texttt{tail}(A,C),\texttt{length}(C,D),
    suc(D,B).\displaystyle\ \ \ \texttt{suc}(D,B).
  • HO Optimal Background: succ, zero, fold.

  • HO Optimal Parameters:

    • max_vars: 3

    • max_body: 2

    • max_clause: 2

    • Switches: non_datalog, allow_singletons.

  • HO Solution:

    length(A,B)\displaystyle\texttt{length}(A,B) :-zero(C),fold_a(C,A,B).\displaystyle\mbox{:-}~\texttt{zero}(C),\texttt{fold\_a}(C,A,B).
    fold_p_a(A,B,C)\displaystyle\texttt{fold\_p\_a}(A,B,C) :-suc(A,C).\displaystyle\mbox{:-}~\texttt{suc}(A,C).

C.5 member/2

 

check whether an element is on a list

  • FO Background: head, tail, empty.

  • FO Parameters:

    • max_vars: 3

    • max_body: 2

    • max_clause: 2

    • Switches: enable_recursion

  • FO Solution:

    member(A,B)\displaystyle\texttt{member}(A,B) :-head(A,B).\displaystyle\mbox{:-}~\texttt{head}(A,B).
    member(A,B)\displaystyle\texttt{member}(A,B) :-tail(A,C),member(C,B).\displaystyle\mbox{:-}~\texttt{tail}(A,C),\texttt{member}(C,B).
  • HO Optimal Background: head, tail, empty, any.

  • HO Optimal Parameters:

    • max_vars: 2

    • max_body: 2

    • max_clause: 2

    • Switches:

  • HO Solution:

    member(A,B)\displaystyle\texttt{member}(A,B) :-any_a(A,B).\displaystyle\mbox{:-}~\texttt{any\_a}(A,B).
    any_p_a(A,B)\displaystyle\texttt{any\_p\_a}(A,B) :-head(A,B).\displaystyle\mbox{:-}~\texttt{head}(A,B).

C.6 sorted/1

 

Check whether a list is sorted (non-decreasing)

  • FO Background: empty, geq, head, tail, suc, zero, pred.

  • FO Solution:

    sorted(A)\displaystyle\texttt{sorted}(A) :-tail(A,B),empty(B).\displaystyle\mbox{:-}~\texttt{tail}(A,B),\texttt{empty}(B).
    sorted(A)\displaystyle\texttt{sorted}(A) :-head(A,D),tail(A,B),\displaystyle\mbox{:-}~\texttt{head}(A,D),\texttt{tail}(A,B),
    head(B,C),geq(C,D),\displaystyle\ \ \ \texttt{head}(B,C),\texttt{geq}(C,D),
    sorted(B).\displaystyle\ \ \ \texttt{sorted}(B).
  • HO Background: empty, geq, head, tail, suc, zero, pred, fold.

  • HO Solution:

    sorted(A)\displaystyle\texttt{sorted}(A) :-zero(C),fold_a(C,A,B).\displaystyle\mbox{:-}~\texttt{zero}(C),\texttt{fold\_a}(C,A,B).
    fold_p_a(A,B,C)\displaystyle\texttt{fold\_p\_a}(A,B,C) :-pred(B,C),geq(C,A).\displaystyle\mbox{:-}~\texttt{pred}(B,C),\texttt{geq}(C,A).

C.7 reverse/2

 

Reverse a list

  • FO Background: empty, app, head, tail.

  • FO Parameters:

    • max_vars: 5

    • max_body: 5

    • max_clause: 2

    • Switches: enable_recursion

  • FO Solution:

    reverse(A,B)\displaystyle\texttt{reverse}(A,B) :-empty(A),empty(B).\displaystyle\mbox{:-}~\texttt{empty}(A),\texttt{empty}(B).
    reverse(A,B)\displaystyle\texttt{reverse}(A,B) :-head(A,D),tail(A,E),\displaystyle\mbox{:-}~\texttt{head}(A,D),\texttt{tail}(A,E),
    reverse(E,C),app(C,D,B).\displaystyle\ \ \ \texttt{reverse}(E,C),\texttt{app}(C,D,B).
  • HO optimal Background: empty, head, tail, fold.

  • HO optimal Parameters:

    • max_vars: 5

    • max_body: 5

    • max_clause: 2

    • Switches: enable_recursion

  • HO Solution:

    reverse(A,B)\displaystyle\texttt{reverse}(A,B) :-empty(C),\displaystyle\mbox{:-}~\texttt{empty}(C),
    fold_a(C,A,B).\displaystyle\ \ \ \texttt{fold\_a}(C,A,B).
    fold_p_a(A,B,C)\displaystyle\texttt{fold\_p\_a}(A,B,C) :-head(C,B),tail(C,A).\displaystyle\mbox{:-}~\texttt{head}(C,B),\texttt{tail}(C,A).

C.8 dropLast/2

 

given a list of lists, drop the last element from each list

  • FO Background:con, tail, empty, reverse

  • FO Parameters:

    • max_vars: 8

    • max_body: 6

    • max_clause: 2

    • Switches: enable_recursion

  • FO Solution:

    dropLast(A,B):-\displaystyle\texttt{dropLast}(A,B)\mbox{:-}~ empty(A),empty(B).\displaystyle\texttt{empty}(A),\texttt{empty}(B).
    dropLast(A,B):-\displaystyle\texttt{dropLast}(A,B)\mbox{:-}~ con(A,B,C),reverse(C,E),\displaystyle\texttt{con}(A,B,C),\texttt{reverse}(C,E),
    tail(E,F),reverse(F,G),\displaystyle\texttt{tail}(E,F),\texttt{reverse}(F,G),
    con(B,G,H),dropLast(D,H).\displaystyle\texttt{con}(B,G,H),\texttt{dropLast}(D,H).
  • HO optimal Background: reverse, tail, map

  • HO optimal Parameters:

    • max_vars: 5

    • max_body: 3

    • max_clause: 3

    • Switches:

  • HO Solution:

    dropLast(A,B):-\displaystyle\texttt{dropLast}(A,B)\mbox{:-}~ map(map_p_a,A,B).\displaystyle\texttt{map}(\texttt{map\_p\_a},A,B).
    map_p_a(A,B):-\displaystyle\texttt{map\_p\_a}(A,B)\mbox{:-}~ reverse(A,C),tail(C,D),\displaystyle\texttt{reverse}(A,C),\texttt{tail}(C,D),
    reverse(D,B).\displaystyle\texttt{reverse}(D,B).

C.9 encryption/2

 

convert characters to integers, add 22 to each of them, then convert them back

  • FO Background: pred, char_to_int, int_to_char, head, con, tail, empty

  • FO Parameters:

    • max_vars: 9

    • max_body: 10

    • max_clause: 2

    • Switches: enable_recursion

  • FO Solution:

    encryption(A,B):-\displaystyle\texttt{encryption}(A,B)\mbox{:-}~ empty(A),empty(B).\displaystyle\texttt{empty}(A),\texttt{empty}(B).
    encryption(A,B):-\displaystyle\texttt{encryption}(A,B)\mbox{:-}~ head(A,C),head(A,D),\displaystyle\texttt{head}(A,C),\texttt{head}(A,D),
    cons(B,E,F),\displaystyle\texttt{cons}(B,E,F),
    char_to_int(C,G),pred(G,H),\displaystyle\texttt{char\_to\_int}(C,G),\texttt{pred}(G,H),
    pred(H,I),int_to_char(I,E),\displaystyle\texttt{pred}(H,I),\texttt{int\_to\_char}(I,E),
    encryption(D,F).\displaystyle\texttt{encryption}(D,F).
  • HO optimal Background: char_to_int, int_to_char, pred, map

  • HO optimal Parameters:

    • max_vars: 5

    • max_body: 4

    • max_clause: 2

    • Switches:

  • HO Solution:

    encryption(A,B):-\displaystyle\texttt{encryption}(A,B)\mbox{:-}~ map_a(A,B).\displaystyle\texttt{map\_a}(A,B).
    map_p_a(A,B):-\displaystyle\texttt{map\_p\_a}(A,B)\mbox{:-}~ char_to_int(A,E),pred(E,D),\displaystyle\texttt{char\_to\_int}(A,E),\texttt{pred}(E,D),
    pred(D,C),int_to_char(C,B).\displaystyle\texttt{pred}(D,C),\texttt{int\_to\_char}(C,B).

C.10 repeatN/3

 

Construct a list made of the input list argument repeated nn times.

  • FO Background: empty, app1, zero, pred.

  • FO Parameters:

    • max_vars: 5

    • max_body: 3

    • max_clause: 2

    • Switches: enable_recursion, non_datalog,
      allow_singletons

  • FO Solution:

    repeatN(A,B,C)\displaystyle\texttt{repeatN}(A,B,C) :-empty(C),zero(B).\displaystyle\mbox{:-}~\texttt{empty}(C),\texttt{zero}(B).
    repeatN(A,B,C)\displaystyle\texttt{repeatN}(A,B,C) :-pred(B,E),repeatN(A,E,D),\displaystyle\mbox{:-}~\texttt{pred}(B,E),\texttt{repeatN}(A,E,D),
    app2(D,A,C).\displaystyle\ \ \ \texttt{app2}(D,A,C).
  • HO Optimal Background: empty, app, zero, pred, iterate.

  • HO Optimal Parameters:

    • max_vars: 4

    • max_body: 2

    • max_clause: 2

    • Switches:

  • HO Solution:

    repeatN(A,B,C)\displaystyle\texttt{repeatN}(A,B,C) :-empty(D),\displaystyle\mbox{:-}~\texttt{empty}(D),
    iterate_a(D,B,C,A).\displaystyle\ \ \ \texttt{iterate\_a}(D,B,C,A).
    iterate_p_a(A,B,C)\displaystyle\texttt{iterate\_p\_a}(A,B,C) :-app(A,C,B).\displaystyle\mbox{:-}~\texttt{app}(A,C,B).

C.11 rotateN/3

 

Move first element of a list to the end nn times.

  • FO Background: empty, app2, head, tail, less0, zero, eq, pred.

  • FO Parameters:

    • max_vars: 7

    • max_body: 6

    • max_clause: 2

    • Switches: enable_recursion

  • FO Solution:

    rotateN(A,B,C)\displaystyle\texttt{rotateN}(A,B,C) :-eq(B,C),zero(A).\displaystyle\mbox{:-}~\texttt{eq}(B,C),\texttt{zero}(A).
    rotateN(A,B,C)\displaystyle\texttt{rotateN}(A,B,C) :-head(B,D),pred(A,G),\displaystyle\mbox{:-}~\texttt{head}(B,D),\texttt{pred}(A,G),
    less0(A),tail(B,E),\displaystyle\ \ \ \texttt{less0}(A),\texttt{tail}(B,E),
    app(E,D,F),rotateN(G,F,C).\displaystyle\ \ \ \texttt{app}(E,D,F),\texttt{rotateN}(G,F,C).
  • HO Optimal Background: empty, app2, head, tail, iterate, zero, eq, pred.

  • HO Optimal Parameters:

    • max_vars: 4

    • max_body: 3

    • max_clause: 2

    • Switches:

  • HO Solution:

    rotateN(A,B,C)\displaystyle\texttt{rotateN}(A,B,C) :-iterate_a(B,A,C).\displaystyle\mbox{:-}~\texttt{iterate\_a}(B,A,C).
    iterate_p_a(A,B,C)\displaystyle\texttt{iterate\_p\_a}(A,B,C) :-head(A,D),tail(A,C),\displaystyle\mbox{:-}~\texttt{head}(A,D),\texttt{tail}(A,C),
    app2(C,D,B).\displaystyle\ \ \ \texttt{app2}(C,D,B).

C.12 allSeqN/2

 

Construct a list of lists, consisting of all sequences from 11 to ii with ini\leq n.

  • FO Background:suc, pred, zero, head, head2, tail, tail2, empty, less0

  • FO Parameters:

    • max_vars: 7

    • max_body: 7

    • max_clause: 5

    • Switches: enable_recursion, enable_ho_recursion, non_datalog, allow_singletons

  • FO Solution:

    allSeqN(A,B):-\displaystyle\texttt{allSeqN}(A,B)\mbox{:-}~ zero(C),h_a(C,A,D),g_a(D,B).\displaystyle\texttt{zero}(C),\texttt{h\_a}(C,A,D),\texttt{g\_a}(D,B).
    g_p_a(A,B):-\displaystyle\texttt{g\_p\_a}(A,B)\mbox{:-}~ empty(A),empty(B).\displaystyle\texttt{empty}(A),\texttt{empty}(B).
    g_p_a(A,B):-\displaystyle\texttt{g\_p\_a}(A,B)\mbox{:-}~ head(A,C),tail(A,F),zero(E),\displaystyle\texttt{head}(A,C),\texttt{tail}(A,F),\texttt{zero}(E),
    h_p_a(E,C,D),g_p_a(F,G),\displaystyle\texttt{h\_p\_a}(E,C,D),\texttt{g\_p\_a}(F,G),
    tail2(B,G),head2(B,D).\displaystyle\texttt{tail2}(B,G),\texttt{head2}(B,D).
    h_p_a(A,B,C):-\displaystyle\texttt{h\_p\_a}(A,B,C)\mbox{:-}~ zero(B),empty(C).\displaystyle\texttt{zero}(B),\texttt{empty}(C).
    h_p_a(A,B,C):-\displaystyle\texttt{h\_p\_a}(A,B,C)\mbox{:-}~ pred(B,D),suc(A,E),less0(B),\displaystyle\texttt{pred}(B,D),\texttt{suc}(A,E),\texttt{less0}(B),
    h_p_a(E,D,F),tail2(C,F),\displaystyle\texttt{h\_p\_a}(E,D,F),\texttt{tail2}(C,F),
    head(C,E).\displaystyle\texttt{head}(C,E).
  • HO Optimal Background: suc, zero, ite, map

  • HO Optimal Parameters:

    • max_vars: 4

    • max_body: 3

    • max_clause: 3

    • Switches:

  • HO Solution:

    allSeqN(A,B):-\displaystyle\texttt{allSeqN}(A,B)\mbox{:-}~ zero(C),iterate_a(C,A,D),\displaystyle\texttt{zero}(C),\texttt{iterate\_a}(C,A,D),
    map_a(D,B).\displaystyle\texttt{map\_a}(D,B).
    iterate_p_a(A,B):-\displaystyle\texttt{iterate\_p\_a}(A,B)\mbox{:-}~ suc(A,B).\displaystyle\texttt{suc}(A,B).
    map_p_a(A,B):-\displaystyle\texttt{map\_p\_a}(A,B)\mbox{:-}~ zero(C),iterate_a(C,A,B).\displaystyle\texttt{zero}(C),\texttt{iterate\_a}(C,A,B).

C.13 dropLastK/3

 

Given a list of lists, drop the last kk elements from each list

  • FO Background: pred, eq, zero, tail, reverse, cons, empty

  • FO Parameters:

    • max_vars: 8

    • max_body: 6

    • max_clause: 4

    • Switches: enable_recursion, enable_ho_recursion

  • FO Solution:

    dropLastK(A,B,C):-\displaystyle\texttt{dropLastK}(A,B,C)\mbox{:-}~ zero(A),eq(C,B),eq(B,C).\displaystyle\texttt{zero}(A),\texttt{eq}(C,B),\texttt{eq}(B,C).
    dropLastK(A,B,C):-\displaystyle\texttt{dropLastK}(A,B,C)\mbox{:-}~ pred(A,E),g_a(B,D),\displaystyle\texttt{pred}(A,E),\texttt{g\_a}(B,D),
    dropLastK(E,D,C).\displaystyle\texttt{dropLastK}(E,D,C).
    g_p_a(A,B):-\displaystyle\texttt{g\_p\_a}(A,B)\mbox{:-}~ empty(A),empty(B).\displaystyle\texttt{empty}(A),\texttt{empty}(B).
    g_p_a(A,B):-\displaystyle\texttt{g\_p\_a}(A,B)\mbox{:-}~ cons(A,C,D),reverse(C,E),\displaystyle\texttt{cons}(A,C,D),\texttt{reverse}(C,E),
    tail(E,F),reverse(F,G),\displaystyle\texttt{tail}(E,F),\texttt{reverse}(F,G),
    cons(B,G,H),g_p_a(D,H).\displaystyle\texttt{cons}(B,G,H),\texttt{g\_p\_a}(D,H).
  • HO Optimal Background: pred, eq, zero, tail, reverse, map

  • HO Optimal Parameters:

    • max_vars: 5

    • max_body: 3

    • max_clause: 3

    • Switches: enable_recursion

  • HO Solution:

    dropLastK(A,B,C):-\displaystyle\texttt{dropLastK}(A,B,C)\mbox{:-}~ eq(C,B),zero(A).\displaystyle\texttt{eq}(C,B),\texttt{zero}(A).
    dropLastK(A,B,C):-\displaystyle\texttt{dropLastK}(A,B,C)\mbox{:-}~ pred(A,E),map(B,D),\displaystyle\texttt{pred}(A,E),\texttt{map}(B,D),
    dropLastK(E,D,C).\displaystyle\texttt{dropLastK}(E,D,C).
    map_p_a(A,B):-\displaystyle\texttt{map\_p\_a}(A,B)\mbox{:-}~ reverse(A,D),tail(D,C),\displaystyle\texttt{reverse}(A,D),\texttt{tail}(D,C),
    reverse(C,B).\displaystyle\texttt{reverse}(C,B).

C.14 firstHalf/2

 

Check whether the second argument is equal to the first half of the first argument

  • FO Background: head, tail, cons, app, true, empty, suc, pred, zero, len

  • FO Parameters:

    • max_vars: 8

    • max_body: 7

    • max_clause: 3

    • Switches:

  • FO Solution:

    firstHalf(A,B):-\displaystyle\texttt{firstHalf}(A,B)\mbox{:-}~ len(A,C),g_a(A,C,B).\displaystyle\texttt{len}(A,C),\texttt{g\_a}(A,C,B).
    g_p_a(A,B,C):-\displaystyle\texttt{g\_p\_a}(A,B,C)\mbox{:-}~ true(A),zero(B),empty(C).\displaystyle\texttt{true}(A),\texttt{zero}(B),\texttt{empty}(C).
    g_p_a(A,B,C):-\displaystyle\texttt{g\_p\_a}(A,B,C)\mbox{:-}~ pred(B,D),head(A,F),\displaystyle\texttt{pred}(B,D),\texttt{head}(A,F),
    tail(A,G),pred(D,E),\displaystyle\texttt{tail}(A,G),\texttt{pred}(D,E),
    g_a(G,E,H),cons(C,F,H).\displaystyle\texttt{g\_a}(G,E,H),\texttt{cons}(C,F,H).
  • HO Optimal Background: head, tail, pred, len, iterateStep

  • HO Optimal Parameters:

    • max_vars: 3

    • max_body: 2

    • max_clause: 3

    • Switches:

  • HO Solution:

    firstHalf(A,B):-\displaystyle\texttt{firstHalf}(A,B)\mbox{:-}~ len(A,C),\displaystyle\texttt{len}(A,C),
    iterateStep_a(A,C,B).\displaystyle\texttt{iterateStep\_a}(A,C,B).
    iterateStep_p_a(A,B):-\displaystyle\texttt{iterateStep\_p\_a}(A,B)\mbox{:-}~ pred(A,C),pred(C,B).\displaystyle\texttt{pred}(A,C),\texttt{pred}(C,B).
    iterateStep_q_a(A,B,C):-\displaystyle\texttt{iterateStep\_q\_a}(A,B,C)\mbox{:-}~ head(A,B),tail(A,C).\displaystyle\texttt{head}(A,B),\texttt{tail}(A,C).

C.15 lastHalf/2

 

check whether the second argument is equal to the last half of the first argument

  • FO Background: empty, tail, front, last, app

  • FO Parameters:

    • max_vars: 6

    • max_body: 5

    • max_clause: 3

    • Switches:

  • FO Solution:

    lastHalf(A,B):-\displaystyle\texttt{lastHalf}(A,B)\mbox{:-}~ empty(B),empty(A).\displaystyle\texttt{empty}(B),\texttt{empty}(A).
    lastHalf(A,B):-\displaystyle\texttt{lastHalf}(A,B)\mbox{:-}~ tail(A,B),empty(B).\displaystyle\texttt{tail}(A,B),\texttt{empty}(B).
    lastHalf(A,B):-\displaystyle\texttt{lastHalf}(A,B)\mbox{:-}~ front(A,C),last(A,F),\displaystyle\texttt{front}(A,C),\texttt{last}(A,F),
    tail(C,E),lastHalf(E,D),\displaystyle\texttt{tail}(C,E),\texttt{lastHalf}(E,D),
    app(D,F,B).\displaystyle\texttt{app}(D,F,B).
  • HO Optimal Background: front, app2, reverse, empty, caseList

  • HO optimal Parameters:

    • max_vars: 5

    • max_body: 3

    • max_clause: 4

    • Switches:

  • HO Solution:

    lastHalf(A,B):-\displaystyle\texttt{lastHalf}(A,B)\mbox{:-}~ reverse(A,C),\displaystyle\texttt{reverse}(A,C),
    caseList_a(C,B).\displaystyle\texttt{caseList\_a}(C,B).
    caseList_p_a(A):-\displaystyle\texttt{caseList\_p\_a}(A)\mbox{:-}~ empty(A).\displaystyle\texttt{empty}(A).
    caseList_r_a(A,B,C):-\displaystyle\texttt{caseList\_r\_a}(A,B,C)\mbox{:-}~ front(B,E),\displaystyle\texttt{front}(B,E),
    caseList_a(E,D),\displaystyle\texttt{caseList\_a}(E,D),
    app(D,A,C).\displaystyle\texttt{app}(D,A,C).

C.16 of1And2/1

 

check whether a list consists only of 11s and 22

  • FO Background: suc, zero, cons1, empty.

  • FO Parameters:

    • max_vars: 5

    • max_body: 5

    • max_clause: 3

    • Switches: enable_recursion

  • FO Solution:

    of1And2(A)\displaystyle\texttt{of1And2}(A) :-empty(A).\displaystyle\mbox{:-}~\texttt{empty}(A).
    of1And2(A)\displaystyle\texttt{of1And2}(A) :-cons1(A,B,C),zero(D),suc(D,B),\displaystyle\mbox{:-}~\texttt{cons1}(A,B,C),\texttt{zero}(D),\texttt{suc}(D,B),
    of1And2(B).\displaystyle\ \ \ \texttt{of1And2}(B).
    of1And2(A)\displaystyle\texttt{of1And2}(A) :-cons1(A,B,C),zero(D),suc(D,E),\displaystyle\mbox{:-}~\texttt{cons1}(A,B,C),\texttt{zero}(D),\texttt{suc}(D,E),
    suc(E,B),of1And2(B).\displaystyle\ \ \ \texttt{suc}(E,B),\texttt{of1And2}(B).
  • HO Optimal Background: suc, zero, cons, empty. try.

  • HO Optimal Parameters:

    • max_vars: 3

    • max_body: 4

    • max_clause: 3

    • Switches: enable_recursion

  • HO Solution:

    of1And2(A)\displaystyle\texttt{of1And2}(A) :-empty(A).\displaystyle\mbox{:-}~\texttt{empty}(A).
    of1And2(A)\displaystyle\texttt{of1And2}(A) :-cons(A,C,B),try_a(C),\displaystyle\mbox{:-}~\texttt{cons}(A,C,B),\texttt{try\_a}(C),
    of1And2(B).\displaystyle\ \ \ \texttt{of1And2}(B).
    try_p_a(A)\displaystyle\texttt{try\_p\_a}(A) :-zero(B),suc(B,A).\displaystyle\mbox{:-}~\texttt{zero}(B),\texttt{suc}(B,A).
    try_q_a(A)\displaystyle\texttt{try\_q\_a}(A) :-zero(B),suc(B,C),suc(C,A).\displaystyle\mbox{:-}~\texttt{zero}(B),\texttt{suc}(B,C),\texttt{suc}(C,A).

C.17 isPalindrome/1

 

Check whether a list is a palindrome (the same read normally and in reverse)

  • FO Background: head, tail, empty, front, last.

  • FO Parameters:

    • max_vars: 4

    • max_body: 5

    • max_clause: 3

    • Switches: enable_recursion

  • FO Solution:

    isPalindrome(A)\displaystyle\texttt{isPalindrome}(A) :-empty(A).\displaystyle\mbox{:-}~\texttt{empty}(A).
    isPalindrome(A)\displaystyle\texttt{isPalindrome}(A) :-front(A,B),empty(B).\displaystyle\mbox{:-}~\texttt{front}(A,B),\texttt{empty}(B).
    isPalindrome(A)\displaystyle\texttt{isPalindrome}(A) :-head(A,D),tail(A,B),\displaystyle\mbox{:-}~\texttt{head}(A,D),\texttt{tail}(A,B),
    front(B,C),last(B,D),\displaystyle\ \ \ \texttt{front}(B,C),\texttt{last}(B,D),
    isPalindrome(C).\displaystyle\ \ \ \texttt{isPalindrome}(C).
  • HO Optimal Background: empty, any, front, last, condList.

  • HO Optimal Parameters:

    • max_vars: 3

    • max_body: 3

    • max_clause: 3

    • Switches:

  • HO Solution:

    isPalindrome(A)\displaystyle\texttt{isPalindrome}(A) :-condlist_a(A).\displaystyle\mbox{:-}~\texttt{condlist\_a}(A).
    condlist_p_a(A,B)\displaystyle\texttt{condlist\_p\_a}(A,B) :-any(A),empty(B).\displaystyle\mbox{:-}~\texttt{any}(A),\texttt{empty}(B).
    condlist_p_a(A,B)\displaystyle\texttt{condlist\_p\_a}(A,B) :-last(B,A),front(B,C),\displaystyle\mbox{:-}~\texttt{last}(B,A),\texttt{front}(B,C),
    condlist_a(C).\displaystyle\ \ \ \texttt{condlist\_a}(C).

C.18 depth/2

 

find the depth of a tree

  • FO Background: eq, children, zero, suc, empty, tail, head, max, g_a

  • FO Parameters:

    • max_vars: 7

    • max_body: 5

    • max_clause: 3

    • Switches: enable_recursion,enable_ho_recursion

  • FO Solution:

    depth(A,B):-\displaystyle\texttt{depth}(A,B)\mbox{:-}~ zero(D),children(A,C),\displaystyle\texttt{zero}(D),\texttt{children}(A,C),
    g_a(D,C,E),suc(E,B).\displaystyle\texttt{g\_a}(D,C,E),\texttt{suc}(E,B).
    g_p_a(A,B,C):-\displaystyle\texttt{g\_p\_a}(A,B,C)\mbox{:-}~ eq(A,C),empty(B).\displaystyle\texttt{eq}(A,C),\texttt{empty}(B).
    g_p_a(A,B,C):-\displaystyle\texttt{g\_p\_a}(A,B,C)\mbox{:-}~ tail(B,E),head(B,D),depth(D,F),\displaystyle\texttt{tail}(B,E),\texttt{head}(B,D),\texttt{depth}(D,F),
    max(A,F,G),g_p_a(G,E,C).\displaystyle\texttt{max}(A,F,G),\texttt{g\_p\_a}(G,E,C).
  • HO Optimal Background: children, max, zero, suc, fold

  • HO Optimal Parameters:

    • max_vars: 5

    • max_body: 4

    • max_clause: 2

    • Switches: enable_recursion

  • HO Solution:

    depth(A,B):-\displaystyle\texttt{depth}(A,B)\mbox{:-}~ children(A,C),zero(E),\displaystyle\texttt{children}(A,C),\texttt{zero}(E),
    fold_a(E,C,D),suc(D,B).\displaystyle\texttt{fold\_a}(E,C,D),\texttt{suc}(D,B).
    fold_p_a(A,B,C):-\displaystyle\texttt{fold\_p\_a}(A,B,C)\mbox{:-}~ depth(B,D),max(D,A,C).\displaystyle\texttt{depth}(B,D),\texttt{max}(D,A,C).

C.19 isBranch/2

 

check whether a given list is a branch of the tree

  • FO Background: children, root, head, head2, tail, g_a

  • FO Parameters:

    • max_vars: 5

    • max_body: 5

    • max_clause: 4

    • Switches: enable_recursion,enable_ho_recursion

  • FO Solution:

    isBranch(A,B):-\displaystyle\texttt{isBranch}(A,B)\mbox{:-}~ tail(B,D),children(A,D),\displaystyle\texttt{tail}(B,D),\texttt{children}(A,D),
    root(A,C),head2(B,C).\displaystyle\texttt{root}(A,C),\texttt{head2}(B,C).
    isBranch(A,B):-\displaystyle\texttt{isBranch}(A,B)\mbox{:-}~ root(A,C),children(A,E),\displaystyle\texttt{root}(A,C),\texttt{children}(A,E),
    tail(B,D),g_a(E,D),\displaystyle\texttt{tail}(B,D),\texttt{g\_a}(E,D),
    head2(B,C).\displaystyle\texttt{head2}(B,C).
    g_p_a(A,B):-\displaystyle\texttt{g\_p\_a}(A,B)\mbox{:-}~ head(A,C),isBranch(C,B).\displaystyle\texttt{head}(A,C),\texttt{isBranch}(C,B).
    g_p_a(A,B):-\displaystyle\texttt{g\_p\_a}(A,B)\mbox{:-}~ tail(A,C),g_p_a(C,B).\displaystyle\texttt{tail}(A,C),\texttt{g\_p\_a}(C,B).
  • HO Optimal Background: head, tail, empty, any, caseTree

  • HO Optimal Parameters:

    • max_vars: 4

    • max_body: 3

    • max_clause: 4

    • Switches: enable_recursion

  • HO Solution:

    isBranch(A,B):-\displaystyle\texttt{isBranch}(A,B)\mbox{:-}~ casetree_a(A,B).\displaystyle\texttt{casetree\_a}(A,B).
    casetree_p_a(A,B):-\displaystyle\texttt{casetree\_p\_a}(A,B)\mbox{:-}~ tail(B,C),empty(C),\displaystyle\texttt{tail}(B,C),\texttt{empty}(C),
    head(B,A).\displaystyle\texttt{head}(B,A).
    any_p_a(A,B):-\displaystyle\texttt{any\_p\_a}(A,B)\mbox{:-}~ tail(B,C),casetree_a(A,C).\displaystyle\texttt{tail}(B,C),\texttt{casetree\_a}(A,C).
    casetree_q_a(A,B,C):-\displaystyle\texttt{casetree\_q\_a}(A,B,C)\mbox{:-}~ head(C,A),any_a(B,C).\displaystyle\texttt{head}(C,A),\texttt{any\_a}(B,C).

C.20 isSubTree/2

 

check whether the second argument is a sub-tree of the first argument.

  • FO Background: head, tail, empty, children, g_a.

  • FO Parameters:

    • max_vars: 4

    • max_body: 2

    • max_clause: 4

    • Switches: enable_recursion,enable_ho_recursion

  • FO Solution:

    g_p_a(A,B)\displaystyle\texttt{g\_p\_a}(A,B) :-children(B,A).\displaystyle\mbox{:-}~\texttt{children}(B,A).
    g_p_a(A,B)\displaystyle\texttt{g\_p\_a}(A,B) :-head(A,B).\displaystyle\mbox{:-}~\texttt{head}(A,B).
    g_p_a(A,B)\displaystyle\texttt{g\_p\_a}(A,B) :-tail(A,C),g_a(C,B).\displaystyle\mbox{:-}~\texttt{tail}(A,C),\texttt{g\_a}(C,B).
    isSubTree(A,B)\displaystyle\texttt{isSubTree}(A,B) :-children(A,C),g_p_a(C,B).\displaystyle\mbox{:-}~\texttt{children}(A,C),\texttt{g\_p\_a}(C,B).
  • HO Optimal Background: children, any, eq1.

  • HO Optimal Parameters:

    • max_vars: 3

    • max_body: 2

    • max_clause: 3

    • Switches: enable_recursion

  • HO Solution:

    isSubTree(A,B)\displaystyle\texttt{isSubTree}(A,B) :-eq(A,B).\displaystyle\mbox{:-}~\texttt{eq}(A,B).
    isSubTree(A,B)\displaystyle\texttt{isSubTree}(A,B) :-children(A,C),\displaystyle\mbox{:-}~\texttt{children}(A,C),
    any_a(C,B).\displaystyle\ \ \ \texttt{any\_a}(C,B).
    any_p_a(A,B)\displaystyle\texttt{any\_p\_a}(A,B) :-isSubTree(A,B).\displaystyle\mbox{:-}~\texttt{isSubTree}(A,B).

C.21 addN/3

add nn to every element of a list (with no addition predicate in the background knowledge)

  • FO Background: suc, pred, zero, eq, less0, cons, cons2, empty, g_a

  • FO Parameters:

    • max_vars: 6

    • max_body: 4

    • max_clause: 4

    • Switches: enable_recursion,enable_ho_recursion

  • FO Solution:

    addN(A,B,C):-\displaystyle\texttt{addN}(A,B,C)\mbox{:-}~ zero(A),eq(B,C).\displaystyle\texttt{zero}(A),\texttt{eq}(B,C).
    addN(A,B,C):-\displaystyle\texttt{addN}(A,B,C)\mbox{:-}~ less0(A),g_a(B,D),\displaystyle\texttt{less0}(A),\texttt{g\_a}(B,D),
    pred(A,E),addN(E,D,C).\displaystyle\texttt{pred}(A,E),\texttt{addN}(E,D,C).
    g_p_a(A,B):-\displaystyle\texttt{g\_p\_a}(A,B)\mbox{:-}~ empty(B),empty(A).\displaystyle\texttt{empty}(B),\texttt{empty}(A).
    g_p_a(A,B):-\displaystyle\texttt{g\_p\_a}(A,B)\mbox{:-}~ cons(A,C,D),suc(C,E),\displaystyle\texttt{cons}(A,C,D),\texttt{suc}(C,E),
    g_p_a(D,F),cons2(B,E,F).\displaystyle\texttt{g\_p\_a}(D,F),\texttt{cons2}(B,E,F).
  • HO Optimal Background: suc, eq, caseint, map

  • HO Optimal Parameters:

    • max_vars: 4

    • max_body: 2

    • max_clause: 4

    • Switches:

  • HO Solution:

    addN(A,B,C):-\displaystyle\texttt{addN}(A,B,C)\mbox{:-}~ caseint_a(A,B,C).\displaystyle\texttt{caseint\_a}(A,B,C).
    map_p_a(A,B):-\displaystyle\texttt{map\_p\_a}(A,B)\mbox{:-}~ suc(A,B).\displaystyle\texttt{suc}(A,B).
    caseint_q_a(A,B,C):-\displaystyle\texttt{caseint\_q\_a}(A,B,C)\mbox{:-}~ map_a(B,D),\displaystyle\texttt{map\_a}(B,D),
    caseint_a(A,D,C).\displaystyle\texttt{caseint\_a}(A,D,C).
    caseint_p_a(A,B):-\displaystyle\texttt{caseint\_p\_a}(A,B)\mbox{:-}~ eq(A,B).\displaystyle\texttt{eq}(A,B).

C.22 mulFromSuc/3

 

Multiply two numbers (with no addition predicate in the background knowledge).

  • FO Background: suc, pred, eq, zero, less0, g_a, h_a.

  • FO Parameters:

    • max_vars: 6

    • max_body: 4

    • max_clause: 5

    • Switches: allow_singletons, non_datalog.

  • FO Solution:

    mulFromSuc(A,B,C)\displaystyle\texttt{mulFromSuc}(A,B,C) :-zero(D),g_a(D,A,C,B).\displaystyle\mbox{:-}~\texttt{zero}(D),\texttt{g\_a}(D,A,C,B).
    g_p_a(A,B,C,D)\displaystyle\texttt{g\_p\_a}(A,B,C,D) :-eq(A,C),zero(B).\displaystyle\mbox{:-}~\texttt{eq}(A,C),\texttt{zero}(B).
    g_p_a(A,B,C,D)\displaystyle\texttt{g\_p\_a}(A,B,C,D) :-pred(B,E),less0(B),\displaystyle\mbox{:-}~\texttt{pred}(B,E),\texttt{less0}(B),
    h_a(A,D,F),g_a(F,E,C,D).\displaystyle\ \ \ \texttt{h\_a}(A,D,F),\texttt{g\_a}(F,E,C,D).
    h_p_a(A,B,C)\displaystyle\texttt{h\_p\_a}(A,B,C) :-eq(A,C),zero(B).\displaystyle\mbox{:-}~\texttt{eq}(A,C),\texttt{zero}(B).
    h_p_a(A,B)\displaystyle\texttt{h\_p\_a}(A,B) :-suc(A,E),less0(B),\displaystyle\mbox{:-}~\texttt{suc}(A,E),\texttt{less0}(B),
    pred(B,D),h_a(E,D,C).\displaystyle\ \ \ \texttt{pred}(B,D),\texttt{h\_a}(E,D,C).
  • HO Optimal Background: suc, zero1, iterate.

  • HO Optimal Parameters:

    • max_vars: 4

    • max_body: 2

    • max_clause: 3

    • Switches:

  • HO Solution:

    mulFromSuc(A,B)\displaystyle\texttt{mulFromSuc}(A,B) :-zero1(D),\displaystyle\mbox{:-}~\texttt{zero1}(D),
    iterate_a(D,A,C,B).\displaystyle\ \ \ \texttt{iterate\_a}(D,A,C,B).
    iterate_p_a(A,B,C)\displaystyle\texttt{iterate\_p\_a}(A,B,C) :-iterate_a(A,C,B).\displaystyle\mbox{:-}~\texttt{iterate\_a}(A,C,B).
    iterate_p_a(A,B)\displaystyle\texttt{iterate\_p\_a}(A,B) :-suc(A,B).\displaystyle\mbox{:-}~\texttt{suc}(A,B).