Skip to content

Functions

Injectable Predicates

A Logica predicate is referred to as concrete when it evaluates to a specific table of values. All the predicates we have discussed so far fall into this category, as they are defined either by:

  • A set of facts, or
  • Finite multisets derived from other predicates.

TIP

An easy way to determine if a predicate is concrete is to check whether it can be output as a table.

Injectable predicates, on the other hand, compute some of their arguments dynamically based on input arguments provided during evaluation.

Example: Adjusting employee salaries using an auxiliary predicate.

Employee(name: "Alice", salary: 50000);
Employee(name: "Bob", salary: 60000);
Employee(name: "Charlie", salary: 55000);

AdjustedSalary(employee_salary, increase_percent, new_salary) :-
  new_salary == employee_salary * (1 + increase_percent / 100);

EmployeeSalaryIncrease(name:, adjusted_salary:) :-
  Employee(name:, salary:),
  AdjustedSalary(salary, 100, adjusted_salary);

In this example, the AdjustedSalary predicate cannot be represented as a simple table. While it mathematically represents a set of triples, this set is either infinite or impractically large (considering finite floating-point precision). Storing or displaying it directly is not feasible.

However, when evaluating the concrete predicate EmployeeSalaryIncrease, we can inject the AdjustedSalary predicate. Injecting a predicate involves replacing its invocation with its definition. For instance, the call to AdjustedSalary(salary, 100, adjusted_salary) is replaced with adjusted_salary == salary * (1 + 100 / 100), enabling the computation of adjusted_salary.

To qualify as injectable, a predicate must be defined using a single non-aggregating conjunctive rule.