1.25 Faits

Les faits sont des triplets de la forme {sujet, relation, objet}. Ils sont stockés dans une base de données. Pour créer une base vide, utilisez Facts.database(). Pour interroger la base de données de l’environnement (base globale contenant tous les symboles et opérateurs du programme), utilisez Facts.env_db().

Utilisez Facts.add_tags pour ajouter un triplet à une base, et Facts.remove_tags pour le retirer.

Les faits peuvent être interrogés à partir de requêtes composées de triplets. Si vous ne cherchez qu’un seul triplet, vous pouvez utiliser Facts.with_tags ou Facts.collect_with_tags. Si vous avez besoin d’une jointure, vous pouvez utiliser Facts.with ou Facts.collect_with pour interroger plusieurs triplets simultanément. Ces fonctions initialisent en interne un itérateur pour la requête et l'exécutent en appelant une fonction de rappel ou en évaluant un bloc pour les variantes _macro.

Vous pouvez obtenir de la persistance avec une seule fonction. Facts.open prend une base de données et un chemin de fichier en argument, rejoue le dump et le journal contenus dans ce fichier, puis l’ouvre en écriture pour journaliser toutes les transactions.

Les transactions rendent leur contenu atomique. Une transaction aboutit soit par un succès, soit par une erreur. En cas d’échec, les actions déjà appliquées sont annulées dans l’ordre inverse. La base est verrouillée en lecture/écriture pendant une transaction. Les transactions peuvent être imbriquées et sont compatibles multi-thread via pthread.

1.25.1 Exemples

Créer une base de données, ajouter et supprimer des triplets, puis effectuer une requête complète (?, ?, ?) :

ikc3> db = Facts.database()
(Ptr) 0x12345678
ikc3> Facts.add_tags(db, "Blade Runner", :is_a, :movie)
true
ikc3> Facts.add_tags(db, "Snow White", :is_a, :movie)
true
ikc3> Facts.remove_tags(db, "Blade Runner", :is_a, :movie)
true
ikc3> Facts.with_tags(db, ?, ?, ?, fn (fact) { puts(inspect(fact)) })
{"Snow White", :is_a, :movie}

Effectuer des requêtes sur les opérateurs de l’environnement global :

ikc3> Facts.with(Facts.env_db(), [[op = ?, :is_a, :op],
ikc3>                             [op, :op_sym, sym = ?]], fn (fact) {
ikc3>   puts("#{inspect(sym)} #{inspect(op)}")
ikc3> })

Le module de configuration d’une instance HTTPd contient un exemple de persistance — la base est chargée lors du chargement du module :

defmodule Config do
  def db = Facts.database()
  Facts.open(db, "db/app.facts")
end

Top : Documentation KC3

Précédent : 1.24 Variable

Suivant : 1.26 Bloc nommé