NB. Chapter 14, Artificial Intelligence

ls =: ('a' ; 1) ; ('b' ; 2) ; box 'c' ; 3

assoc =: dyad define 'try. open ((0 from rank 1 open y.) index_of box x.) from y. catch. 0 end.'

pairlis =: dyad define 'box rank 1 x. stitch y.'

NB. Property list definitions

NB. top-level name/property list chain

name_list =: ''

NB. locate the name/property list pair

name_index =: dyad define 'try. (0 from rank 1 open y.) index_of box x. catch. '''' end.'

NB. get

get =: monad define script
('name' ; 'prop') =. y.
p_list =. ravel open rest name assoc name_list
if. 0 not_equal tally p_list
  do. item =. prop assoc p_list
    if. 0 not_equal item
      do. , open rest item
      else. ''
    end.
  else. ''
end.
)

NB. put

put =: monad define script
('name' ; 'prop' ; 'value') =. y.
n_index =. name name_index name_list
if. nullp n_index  NB. empty property list
    do. name_list =: box name ; box box prop ; box value
    ''
  elseif. n_index = tally name_list  NB. new name for property list
    do. name_list =: name_list append box name ; box box prop ; box value
    ''
  elseif. 1  NB. either add a new property or change a property value
    do. p_list =. ravel open rest open n_index from name_list
      p_index =. prop name_index p_list
      if. p_index = tally p_list  NB. add a new property
        do. name_list =: (box name ; box p_list append box prop ; box value) n_index amend name_list
        ''
        else. name_list =: (box name ; box (box prop ; box value) p_index amend p_list) n_index amend name_list
        ''
      end.
end.
)

property_list =: monad define 'try. open rest open ((0 from rank 1 open name_list) index_of box y.) from name_list catch. '''' end.'

property_names =: monad define 'try. 0 from rank 1 open name_list catch. '''' end.'

put 'jack' ; 'name' ; 'John Howland'
put 'jack' ; 'height' ; 76
put 'jack' ; 'age' ; 55
put 'glynne' ; 'name' ; 'Glynne Howland'
put 'glynne' ; 'age' ; '?'
put 'glynne' ; 'spouse' ; 'jack'
put 'jack' ; 'spouse' ; 'glynne'

tree =: (('a' ; 'b') ; box ('c' ; 'd')) ; box (('e' ; 'f') ; box ('g' ; 'h'))

display_leaves =: monad define script
if. nullp y.
  do. ''
  else. if. boxp y.
          do. display_leaves head y.
              display_leaves rest y.
          else. display y.
        end.
end.
)

traced_display_leaves =: monad define script
entering y.
if. nullp y.
  do. leaving ''
  else. if. boxp y.
          do. leaving traced_display_leaves head y.
              leaving traced_display_leaves rest y.
          else. display y.
        end.
end.
)

display_leaves1 =: monad define script
if. nullp y.
  do. ''
  else. if. boxp y.
          do. display_leaves1 rest y.
              display_leaves1 head y.
          else. display y.
        end.
end.
)

traced_display_leaves1 =: monad define script
entering y.
if. nullp y.
  do. leaving ''
  else. if. boxp y.
          do. leaving traced_display_leaves1 rest y.
              leaving traced_display_leaves1 head y.
          else. display y.
        end.
end.
)

remember =: monad define script
('node' ; 'property' ; 'value') =. y.
if. 'root' match node
    do. 'no'
  elseif. value match get node ; property
    do. 'yes'
  elseif. 1
    do. remember (get node ; 'isa') ; property ; value
end.
)

put 'physical-entity' ; 'isa' ; 'root'
put 'living-thing' ; 'isa' ; 'physical-entity'
put 'carnivore' ; 'isa' ; 'living-thing'
put 'human' ; 'isa' ; 'carnivore'
put 'woman' ; 'isa' ; 'human'
put 'man' ; 'isa' ; 'human'
put 'queen-elizabeth' ; 'isa' ; 'woman'
put 'prince-philip' ; 'isa' ; 'man'
put 'mother' ; 'isa' ; 'woman'
put 'father' ; 'isa' ; 'man'
put 'carnivore' ; 'eats' ; 'meat'
put 'human' ; 'contains' ; 'soul'

traced_remember =: monad define script
entering y.
('node' ; 'property' ; 'value') =. y.
if. 'root' match node
    do. leaving 'no'
  elseif. value match get node ; property
    do. leaving 'yes'
  elseif. 1
    do. leaving traced_remember (get node ; 'isa') ; property ; value
end.
)

