Submission of knowledge in Prolog - how to store data?

since I received criticism regarding my data structure in Prolog, I asked experts here for alternative solutions.

As an example, I have a decription recipe dataset in XML

<recipeml fileversion="13.8.2014">
  <recipe>
    <head>
      <title>Green Soup</title>
    </head>
    <ing-div type="titled">
        <title>soup</title>
        <ingredients>
          <ing>
            <amt><qty>500</qty><unit>gramm</unit></amt>
            <item>pea</item>
          </ing>
          <ing>
            <amt><qty>200</qty><unit>ml</unit></amt>
            <item>cream</item>
          </ing>
          ...
        </ingredients>
    </ing-div>  
    <directions>
      <step>Do something, cooking ....</step>
      <step>Next do again something...</step>
      ...
    </directions>
  </recipe>
  <recipe>
   ...
  </recipe>
  ...
</recipeml>

I want to save it in Prolog as an iterative tree of elements using lists:

database([element('recipeml',[version=0.5], 
    [element('recipe',[],
        [element('head',[],
            [element('title',[],['Green Soup']
            )]
        ),
        element('ing-div',[type=titled], 
            [element('title',[],['soup']),
             element('ingredients',[],
                [element(ing,[],
                    [ element(amt,[],
                        [ element(qty,[],['500']), element(unit,[],[gramm]),]),
                    element(item,[],['pea']) 
                    ]),
                element(ing,[],
                    [ element(amt,[],
                        [ element(qty,[],['200']), element(unit,[],[ml]),]),
                    element(item,[],['pea']) 
                    ])
                ]
            )]
        )]
    ),
    element('recipe',[],...
    )] 
)]).

What I want to do is easily find recipes based on user input. The user can specify the ingredient or part of the recipe name as input.

I actually ran the elements through

ask_element(Name, Child, Parent) :-
        (
            member( element(Name,_,Child),Parent)
        ;
            member( element(_,_,NewParent),Parent),
            [_|_] = NewParent,
            ask_element(Name, Child, NewParent)
        ).

I have all the recipes with a special ingredient

 findall(RTitle,
            (
            ask_element('recipe',RKnot,Knot),
            ask_element('item',TmpIng,RKnot),
            contains(TmpIng,Ingredient),
            [Ing|_] = TmpIng, % avoid brackets [Egg]
            define_xml_knot(['head','title'],_,RKnot,TmpRTitle),
            [RTitle|_] = TmpRTitle % avoid brackets [Soup]
        ,Bag),

My result is a list of recipe names. If a list of ingredients is entered, I need a second step in the analysis to get a recipe with the most suitable ingredients. Maybe this is not a prologue?

, (), ,

recipe(IDnumber,'Green Soup',ingredients(item(500,gramm,'pea'),item(200,ml,'cream')),steps('Do something','Next step do again something')).

, . , , , ( ), . , . "level(easy)" , recipe() . element(element...) . , IDnumber, "" (recipe(123,X,Y,Z)) . " ", "" ...

Prolog, adquate. .

+4
2

Prolog, XML , Carlo .

, , Prolog. , , , . , , , , ( ), ( , , , ). , level/1 , , . , , . , . , . , , , - . ( , , ). , , . , , .

: , - Logtalk Prolog ( Prolog, GNU Prolog SWI-Prolog). . /, , ., , post.

:- protocol(recipep).

    :- public([
        name/1, ingredient/3, step/1         % descriptors
    ]).

:- end_protocol.


:- object(proto_recipe, implements(recipep)).

    :- public([
        ingredient/1, ingredients/1, steps/1  % utility predicates
    ]).

    ingredient(Ingredient) :-
        ::ingredient(Ingredient,_,_).

    ingredients(Ingredients) :-
        findall(Ingredient, ::ingredient(Ingredient,_,_), Ingredients).

    steps(Steps) :-
        findall(Step, ::step(Step), Steps).

:- end_object.


:- object(green_soup, extends(proto_recipe)).

    name('Green Soup').

    ingredient(pea, 500, gr).
    ingredient(cream, 200, ml).

    step(...).
    ...

:- end_object.


:- object(mashed_peas, extends(proto_recipe)).

    name('Mashed Peas').

    ingredient(pea, 700, gr).
    ingredient(salt, 20, gr).
    ...

:- end_object.

:

?- green_soup::ingredients(Ingredients).
Ingredients = [pea, cream].

?- conforms_to_protocol(Recipe, recipep), Recipe::ingredient(pea).
Recipe = green_soup ;
Recipe = mashed_peas ;
false.

, level/1 . , :

:- category(add_recipe_level_descriptor, complements(proto_recipe)).

    :- public(level/1).
    :- dynamic(level/1).

:- end_category.

. . , :

?- green_soup::assertz(level(hard)).
true.

, :

:- category(recipe_level_default_value, complements(proto_recipe)).

    level(easy).

:- end_category.

:

?- mashed_peas::level(Level).
Level = easy.

(, /), , , , ( ).

+1

SWI-Prolog (xpath), " ". . , findall .., , .

?- database(Db), xpath(Db, //recipe, Recipe).

. , . () , ...

, , library(xpath) GCC XML. SWI/OpenGL...

+2

All Articles