:- object knowledge : [knowledge_base].

knowledge :-
  load(beliefs, beliefs),
  load(lexicon, lexicon).

load(beliefs, _Beliefs) :-
  new_attr(belief),
  new_attr(object),
  new_attr(module),
  new_attr(fact),
  new_attr(desire),

  findall(beliefs, Object, object(Object), Objects),
  findall(beliefs, Command, command(Command), Commands),
  findall(beliefs, Module, module(Module), Modules),
  findall(beliefs, Belief, belief(Belief), Beliefs),

  load_term(object, [Objects]),
  load_term(belief, Beliefs),
  load_term(module, Modules).
  
load(lexicon, _Lexicon) :-
  new_attr(lexicon),
  findall(Lex, get_lex(Lex), List),
  load_term(lexicon, List).

get_lex(Lex) :-
  call(lexicon, lex(Word, Type, Meaning)),
  Lex = lex(Word, Type, Meaning).

load_term(_Field, []).
load_term(Field, [X|Rest]) :-
  add_attribute(Field, X),
  load_term(Field, Rest).

add_attribute(Field, Term) :-
  add_attr(Field, Term),
  !.

% adds a new field if it doesn't exist
add_attribute(Field, Term) :-
  new_attr(Field),
  add_attr(Field, Term).

:- end_object knowledge.

:- object knowledge_base.

  new_attr(Field) :-
    set_field(Field, []).

  create_field(Field) :-
    show_attr(Field, [_|_]),
    !.
  create_field(Field) :-
    new_attr(Field).

  show_attr(Field, Value) :-
    get_field(Field, Value).

  add_attr(Field, Value) :-
    get_field(Field, OldList),
    add_attr(OldList, Value, NewList),
    set_field(Field, NewList).

  %% add + check duplicates:
  add_attr([], V, [V]) :-
    !.
  add_attr([H|T], H, [H|T]) :-
    !. % bestaat al, skip.
  add_attr([H|T1], V, [H|T2]) :-
    add_attr(T1, V, T2).

  modify_attr(Field, Value, NewValue) :-
    delete_attr(Field, Value),
    !,
    add_attr(Field, NewValue).

  modify_attr(Field, _Value, NewValue) :-
    add_attr(Field, NewValue).

  lookup_attr(Field, Value) :-
    get_field(Field, List),
    !,
    lookup_next_attr(List, Value).

  lookup_attr1(Field, Value) :-
    get_field(Field, List),
    !,
    lookup_next_attr1(List, Value).

  member_attr_fail(Field, Value) :-
    get_field(Field, List),
    not(member(Value, List)),
    !.
    
  lookup_next_attr([], _) :-
    !, fail.
  lookup_next_attr([H|_], H) :-
    !.
  lookup_next_attr([_|T], V) :-
    lookup_next_attr(T, V).
  
  lookup_next_attr1([], _) :-
    !, fail.
  lookup_next_attr1([H|_], H).
  lookup_next_attr1([_|T], V) :-
    lookup_next_attr1(T, V).

  member_attr(Field, Value) :-
    get_field(Field, List),
    member(Value, List).

  delete_attr(Field, Value) :-
    get_field(Field, OldList),
    delete_attr_from_list(OldList, NewList, Value),
    set_field(Field, NewList).

  delete_attr_from_list([], [], _) :-
    !.  % not found, fail | error ?
  delete_attr_from_list([H|T], T, H) :-
    !.
  delete_attr_from_list([H|T1], [H|T2], V) :-
    delete_attr_from_list(T1, T2, V).

:- end_object knowledge_base.
