From a2652fe19b09668779fc36f5cb42c5f9ab6eb95a Mon Sep 17 00:00:00 2001 From: Anne Ogborn Date: Sun, 12 Aug 2018 18:16:42 -0700 Subject: [PATCH] moved all to sep project to relicense for release --- .gitignore | 5 + README.md | 35 +++ anglify.pl | 128 +++++++++ fairy.pl | 68 +++++ fairystory.graphml | 233 ++++++++++++++++ fairystory.png | Bin 0 -> 32331 bytes planner.pl | 324 ++++++++++++++++++++++ plannerb4refactor.pl | 156 +++++++++++ project.odp | Bin 0 -> 52206 bytes run.pl | 28 ++ snail.pl | 322 ++++++++++++++++++++++ snailgarden.graphml | 243 +++++++++++++++++ states.graphml | 633 +++++++++++++++++++++++++++++++++++++++++++ states.png | Bin 0 -> 33693 bytes talespin.pl | 104 +++++++ 15 files changed, 2279 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 anglify.pl create mode 100644 fairy.pl create mode 100644 fairystory.graphml create mode 100644 fairystory.png create mode 100644 planner.pl create mode 100644 plannerb4refactor.pl create mode 100644 project.odp create mode 100644 run.pl create mode 100644 snail.pl create mode 100644 snailgarden.graphml create mode 100644 states.graphml create mode 100644 states.png create mode 100644 talespin.pl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7d60fe7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.*~ +*~ +chatfeedback.txt + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..1f673a6 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# Talespin + +This is my version of the project for the Introduction to SWI-Prolog class. + +Anne Ogborn + + +## Install + +Just have a recent (tested on 7.7.18) SWI-Prolog install + +clone this repo + +## Run + + cd talespin/ + swipl run.pl + ?- print_story. + +## License + +/* + * + * Copyright 2018, Anne Ogborn + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + diff --git a/anglify.pl b/anglify.pl new file mode 100644 index 0000000..aaeccdb --- /dev/null +++ b/anglify.pl @@ -0,0 +1,128 @@ +/* + * + * Copyright 2018, Anne Ogborn + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +:- module(anglify, [ + anglify/2 + ]). +/** Anglify the snail stories + * + */ +anglify(Semantics, English) :- + phrase(as_english([genre(snail)], EnglishList, _), Semantics), + list_english(EnglishList, English), + !. % lame, but ez + +as_english(Ctx, [], Ctx) --> []. +as_english(Ctx, [English | Rest], CtxOut) --> + happening(Ctx, English, Ctx1), + as_english(Ctx1, Rest, CtxOut). + +happening(Ctx, E, Ctx1) --> + [moveall(_, B), moveall(B, C)], + format_desc(Ctx, 'They traveled from ~w and on to ~w.', + [friend(B), friend(C)], + Ctx1, E). % remember E is a string +happening(Ctx, E, Ctx1) --> + [moveall(_, B)], + format_desc(Ctx, 'They crawled along to ~w.', [place(B)], Ctx1, E). +happening(Ctx, E, Ctx) --> + [E], + {string(E)}. +happening(Ctx, E, Ctx1) --> + [blocked_by(Loc, stone)], + format_desc(Ctx, + 'They found the path to ~w blocked by a big round rock!', + [place(Loc)], + Ctx1, + E). +happening(Ctx, E, Ctx1) --> + [unblocked(Friend, stone)], + format_desc(Ctx, + '~w pushed and tugged, and pushed and tugged, and rolled the rock away.', + [friend(Friend)], + Ctx1, + E). +happening(Ctx, E, Ctx1) --> + [gardener_appears], + format_desc(Ctx, '~w', [friend(cratchet)], Ctx1, E). +happening(Ctx, E, Ctx1) --> + [join_party(Friend)], + format_desc(Ctx, + 'Pomatia\'s friend ~w suddenly appeared, and agreed to go along.', + [friend(Friend)], + Ctx1, + E). +happening(Ctx, + "They all had a grand time at the tea party. They drank tea, and ate scones, or leaves, or whatever suited them. Finally it was time to leave.", + Ctx) --> + [attended_tea_party]. +happening(Ctx, + "Mrs. Cratchet went back inside to watch her soap opera. The garden residents sighed with relief.", Ctx) --> + [gardener_leaves]. +happening(Ctx, + "Mrs. Cratchet picked up the rock and threw it at them! The rock wasn\'t in the way any longer!" + , Ctx) --> + [gardener_threw_stone]. +happening(Ctx, + "Pomatia had a particular hard berry they liked to use as a ball. Pomatia decided to take the ball with them." + , Ctx) --> + [take_ball]. +happening(Ctx, + "The friends played with Pomatia\'s ball." + , Ctx) --> + [play_ball]. +happening(Ctx, "", Ctx) --> + [theme(_)]. +happening(Ctx, + "One day Pomatia was invited to tea at the mushrooms beyond the pond. Froggy lived there, and always gave such grand tea parties.", Ctx) --> + [start_message(_)]. +happening(Ctx, "Pomatia bopped their ball with their head. \"Oh No!\" The ball went Splash! in the pond!", Ctx) --> + [lost_ball_in_water]. +happening(Ctx, "The ball drifted to the edge of the pond. Pomatia raced (slowly) to catch it. \"Oh No! The ball will float away!\" But the ball stayed near the edge, and Pomatia was able to grab it.", Ctx) --> + [recover_ball_from_water]. + +happening(Ctx, E, Ctx) --> + [A], + {atom_string(A, E)}. + +format_desc(Ctx, Format, Args, CtxOut, String) --> [], + { + args_atoms(Ctx, Args, AtomArgs, CtxOut), + format(string(String), Format, AtomArgs) + }. + +args_atoms(Ctx, [], [], Ctx). +args_atoms(Ctx, [place(A) | Tail], [Atom | TailOut], Ctx1) :- + memberchk(genre(Genre), Ctx), + Genre:place_desc(A, Short, Long), + ( memberchk(A, Ctx) + -> + Atom = Short, + args_atoms(Ctx, Tail, TailOut, Ctx1) + ; + Atom = Long, + args_atoms([A | Ctx], Tail, TailOut, Ctx1) + ). +args_atoms(Ctx, [friend(A) | Tail], [Atom | TailOut], Ctx1) :- + memberchk(genre(Genre), Ctx), + Genre:friend_desc(A, Short, Long), + ( memberchk(A, Ctx) + -> + Atom = Short, + args_atoms(Ctx, Tail, TailOut, Ctx1) + ; + Atom = Long, + args_atoms([A | Ctx], Tail, TailOut, Ctx1) + ). + +list_english(List, English) :- + atomics_to_string(List, '\n', English). diff --git a/fairy.pl b/fairy.pl new file mode 100644 index 0000000..ac7fcd8 --- /dev/null +++ b/fairy.pl @@ -0,0 +1,68 @@ +/* + * + * Copyright 2018, Anne Ogborn + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +:- module(fairy, [action/2]). + +:- multifile planner:max_plan_len/2. + +planner:max_plan_len(fairy, 12). + +action(bake_pie, + action{ + pre: [loc(home), has_flour, has_berries], + negpre: [], + add: [has_pie], + remove: [has_flour, has_berries], + desc: [$0, used, the, flour, and, berries, + to, bake, a, delicious, pie] + }). +action(walk_to_woods, + action{ + pre: [loc(home)], + negpre: [wolf], + add: [loc(woods)], + remove: [loc(_)], + desc: [$0, walked, deep, into, the, woods] + }). +action(walk_to_grannys, + action{ + pre: [loc(woods)], + negpre: [wolf], + add: [loc(grannys)], + remove: [loc(_)], + desc: [$0, walked, to, grannys, house] + }). +action(greet_by_granny, + action{ + pre: [loc(grannys)], + negpre: [], + add: [saw_granny], + remove: [], + desc: [$0, saw, her, granny] + }). +action(leave_grannys, + action{ + pre: [loc(grannys)], + negpre: [], + add: [loc(woods)], + remove: [loc(_)], + desc: [$0, walked, into, the, woods, headed, home] + }). +action(arrive_home, + action{ + pre: [loc(woods)], + negpre: [wolf], + add: [loc(home)], + remove: [loc(_)], + desc: [$0, arrived, home] + }). + diff --git a/fairystory.graphml b/fairystory.graphml new file mode 100644 index 0000000..08c923d --- /dev/null +++ b/fairystory.graphml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + start + + + + + + + + + + + + + + + + + + woods + + + + + + + + + + + + + + + + + + grannies + + + + + + + + + + + + + + + + + + has_pie + + + + + + + + + + + + + + + + + + bake_pie + + + + + + + + + + + + + + + + + + + walk_to_woods + + + + + + + + + + + + + + + + + + + walk_to_grannies + + + + + + + + + + + + + + + + + + + + + saw_granny + + + + + + + + + + + + + + + + + + + + + leave_grannies + + + + + + + + + + + + + + + + + + + + + + arrive_home + + + + + + + + + + + + + + + + + + + walk_to_woods + + + + + + + + + + + + + + + + diff --git a/fairystory.png b/fairystory.png new file mode 100644 index 0000000000000000000000000000000000000000..426755058ab72caa9b52be4488b97989737d19ea GIT binary patch literal 32331 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 literal 0 HcmV?d00001 diff --git a/planner.pl b/planner.pl new file mode 100644 index 0000000..92ba37b --- /dev/null +++ b/planner.pl @@ -0,0 +1,324 @@ +/* Part of SWI-Prolog + + Author: Anne Ogborn + E-mail: anne@swi-prolog.org + WWW: http://www.swi-prolog.org + Copyright (c) 2018, Anne Ogborn + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +:- module(planner, [ + plan/4, + apply_action_dict/3 + ]). +/** A STRIPS type planner. + * + * This planner depends on action modules, called 'genres', as sets + * of actions. See + * the 'fairy.pl' example for format. + * + * + */ +:- license(bsd). + +% ! plan(+InitConditions:list, +Genre:atom, -Plan:list, +Options:list) +% ! is nondet +% +% Given a set of initial conditions and a Genre, generate different +% plans on backtracking +% +% @arg InitConditions is a list of conditions at the start. Goals +% should be listed as goal(X), and when all X appear in the conditions, +% planning terminates +% @arg Genre is an atomic genre, allowing actions to be defined for +% different genres. +% @arg Plan - a list of action names +% @arg Options - the only available options are order(random) +% (default), which randomizes at each step, and order(first), which +% takes actions in lexical order +% +plan(InitConditions, Genre, Plan, Options) :- + ( member(order(Order), Options) + ; Order = random + ), + list_to_ord_set(InitConditions, OrdCond), + plan_(Genre, + Order, + /*Open*/ [OrdCond-[]], + /* Closed*/[OrdCond], + RPlan), + reverse(RPlan, Plan). + +% Genre is the *|module name|* of the actions +% Order is the argument of the order/1 option +% Open is a list of nodes to explore, as State-Story pairs +% Closed is a list of states to never again put on Open +% RPlan is the plan, with the last action first, +% +% if the Open list is exhausted, +plan_(_, _, [], _, _) :- + !, + fail. +% +% if we've reached a goal state we have a solution. +plan_(_Genre, + _Order, + [State-Story |_], + _Closed, + Story) :- + debug(planner(current), '~q ~q', [State, Story]), + at_goal(State). +% if we have a shaggy dog story, discard from Open +plan_(Genre, + Order, + [_State-Story | Open], + Closed, + FullStory) :- + length(Story, Len), + ( max_plan_len(Genre, MaxLen) + *-> true + ; MaxLen = 18 + ), + Len > MaxLen, + plan_(Genre, Order, Open, Closed, FullStory). +% process head of Open +plan_(Genre, + Order, + [State-Story | Open], + Closed, + FullStory) :- + ordered_possible_action_states(State, Genre, Order, PossibleActions), + actions_children(State, Genre, PossibleActions, Children), + add_unclosed_children_to_open(Story, + Closed, + PossibleActions, + Children, % list of states + Open, + Open1), + add_unique( + Closed, + Children, + Closed1), + plan_(Genre, Order, Open1, [State | Closed1], FullStory). + + +%! ordered_possible_action_states(+State:state, +Genre:atom, +%! +Order:atom, -Possible:list) is det +% +% Give a state list and Genre, return the possible actions +% as a list of action names, sorted in order found if Order=first +% and in random order if Order=random +% +ordered_possible_action_states(State, + Genre, + Order, + Possible) :- + possible_actions(State, Genre, RawPossible), + ( Order = random + -> random_permutation(RawPossible, Possible) + ; RawPossible = Possible + ). + + +%! add_unclosed_children_to_open(+Story:listpair, +Closed:list, +%! +Actions:list, +Children:list, +OpenIn:list, +%! -OpenOut:list) is det +% +% True when OpenOut is the new Open list resulting from adding +% the State-Story pairs in Children to the open list, +% discarding those already in the closed list. +% +% @arg Story the current story so far +% @arg Closed list of States we should ignore +% @arg Actions list of actions that got the children in Children +% @arg Children list of States resulting from the current state via +% the action in the corresponding position of Actions +% @arg OpenIn list of State-Story pairs not yet processed, to be added +% to +% @arg OpenOut the new Open, after adding the Children with the stories +% +% we have no more children to add +add_unclosed_children_to_open( _Story, + _Closed, + _, % action + [], % children + Open, + Open) :- + !. % green +% in the closed set +add_unclosed_children_to_open( Story, + Closed, + [_Action | Actions], + [Child | Children], + Open, + OpenOut) :- + memberchk(Child, Closed), % its in the closed set + !, % green + add_unclosed_children_to_open(Story, + Closed, + Actions, + Children, + Open, + OpenOut). +% already in the open set +add_unclosed_children_to_open( Story, + Closed, + [Action | Actions], + [Child | Children], + Open, + OpenOut) :- + memberchk(Child-_, Open), % it's already in the open set + debug(planner(dup_open), '~q', [Child-[Action | Story]]), + !, % green + add_unclosed_children_to_open(Story, + Closed, + Actions, + Children, + Open, + OpenOut). +% main case +add_unclosed_children_to_open( Story, + Closed, + [Action | Actions], + [Child | Children], + Open, + OpenOut) :- + append(Open, [Child-[Action | Story]], OpenX), + !, % green + add_unclosed_children_to_open(Story, + Closed, + Actions, + Children, + OpenX, + OpenOut). + +% ! add_unique(+In:list, +New:list, +%! -Out:list) is det +% +% prepend those elements of New which are not in +% the In set. Elements of New are added in reverse order, +% and second occurances of elements of New are ignored. +% +add_unique(In, [], In) :- + !. % green +add_unique(In, [NewH| New], Out) :- + memberchk(NewH, In), + !, % green + add_unique(In, New, Out). +add_unique(In, [NewH| New], [NewH | Out]) :- + add_unique(In, New, Out). + +%! at_goal(+State:list) is det +% +% succeeds if we're at the final goal +% +at_goal(Cond) :- + check_goals(Cond, Cond), + !. % green + +check_goals([], _). +check_goals([goal(Goal)|T], Cond) :- + memberchk(Goal, Cond), + check_goals(T, Cond). +check_goals([H|T], Cond) :- + H \= goal(_), + check_goals(T, Cond). + +%! possible_actions(+Cond:list, +Genre:atom, -Possible) is det +% +% succeeds when Possible is the list of actions that can be performed +% from Cond using Genre as the action list. +% +possible_actions(Cond, Genre, Possible) :- + findall(Name, possible_action(Cond, Genre, Name), Possible). + +possible_action(Cond, Genre, Name) :- + Genre:action(Name, Act), + action{ pre:Pre, + negpre: NegPre + } :< Act, + maplist(is_in(Cond), Pre), + maplist(not_in(Cond), NegPre). + +% famulus to swap memberchk's args +is_in(List, Member) :- + memberchk(Member, List). + +not_in(List, Member) :- + \+ memberchk(Member, List). + +%! actions_children(+State:list, +%! +Genre:list, +%! +PossibleActions:list, +%! -Children:list) is det +% +% succeeds when Children is a list of new states resulting +% from applying the members of PossibleActions to State +% +% @arg State the current state +% @arg Genre the module name of the actions +% @arg PossibleActions a list of atom action names. Assumed possible +% @arg Children The subsequent states +% +actions_children(State, Genre, PossibleActions, Children) :- + maplist(apply_action(State, Genre), PossibleActions, Children). + +apply_action(State, Genre, Name, NewState) :- + Genre:action(Name, Action), + apply_action_dict(State, Action, NewState). + +apply_action_dict(State, Action, NewState) :- + action{ + add: Add, + remove: Remove + } :< Action, + my_subtract(State, Remove, S1), + list_to_ord_set(Add, OrdAdd), + ord_union(S1, OrdAdd, NewState). + +%! my_subtract(+A:list, +B:list, -C:list) is det +% +% ord_subtract uses the standard term order, which isn't happy +% when we have a not fully ground term. To avoid it, we build our +% own subtract +% +% Succeeds when C = A - B as set operation, where A must be ground +% and B possibly contains partially ground elements which remove +% all elements of A they unify with +% +my_subtract([], _, []). +my_subtract([H|T], Remove, TOut) :- + memberchk(H, Remove), + !, + my_subtract(T, Remove, TOut). +my_subtract([H|T], Remove, [H|TOut]) :- + my_subtract(T, Remove, TOut). + + +:- multifile planner:max_plan_len/2. + +max_plan_len(nothing, 18). diff --git a/plannerb4refactor.pl b/plannerb4refactor.pl new file mode 100644 index 0000000..c155bb0 --- /dev/null +++ b/plannerb4refactor.pl @@ -0,0 +1,156 @@ +:- module(planner, [ + plan/4 + ]). +/** A planner. + * + * Released under the terms of the SWI-Prolog license + * + * The planner depends on action modules, called 'genres' + * + * + */ + +% ! plan(+InitConditions:list, +Genre:atom, -Plan:list, +Options:list) +% ! is nondet +% +% Given a set of initial conditions and a Genre, generate random plans +% on backtracking +% +% @arg InitConditions is a list of conditions at the start. Goals +% should be listed as goal(X), and when all X appear in the conditions, +% planning terminates +% @arg Genre is an atomic genre, allowing actions to be defined for +% different genres. +% @arg Plan - a list of action names +% @arg Options - the only available options are order(random) +% (default), which randomizes at each step, and order(first), which +% takes actions in lexical order +% +plan(InitConditions, Genre, Plan, Options) :- + ( member(order(Order), Options) + ; Order = random + ), + empty_queue, + list_to_ord_set(InitConditions, OrdCond), + plan_(Genre, + Order, + /*Open*/ [OrdCond], + /* Closed*/[OrdCond], + RPlan), + reverse(RPlan, Plan). + +% Genre is the module of the actions +% Order is the argument of the order/1 option +% Open is a list of nodes to explore, as State-Story pairs +% Closed is a list of nodes to never again put on Open +% RPlan is the plan, with the last action first +% +% if the Open list is exhausted, +plan_(_, _, [], _, _) :- + !, + fail. +% +% if we've reached a goal state we have a solution. +plan_(_Genre, + _Order, + [State-Story |_], + _Closed, + Story) :- + at_goal(State). +plan_(Genre, + Order, + [State-Story | Open], + Closed, + FullStory) :- + ordered_possible_action_states(State-Story, Genre, Order, Possible), + add_unique_children_to_open(State-Story, Genre, Possible, Open, Open1), + plan_(Genre, Order, Open1, [State | Closed], FullStory). + + + +plan_(Cond, _Genre, Prev, _, _, _) :- + member(Cond, Prev), % we've been here before + !, + fail. +plan_(Cond, Genre, _Prev, _SoFar, _Plan, _Order) :- + possible_actions(Cond, Genre, []), % no move from here + !, + fail. +plan_(Cond, _, _, _, _, _) :- + member(dead, Cond), % dead end + !, + fail. +plan_(Cond, Genre, Prev, SoFar, Plan, Order) :- + add_queue(SoFar, Cond), + pop_queue(FirstSoFar, FirstCond), + possible_actions(FirstCond, Genre, RawPossible), + ( Order = random + -> once(random_permutation(RawPossible, Possible)) + ; RawPossible = Possible + ), + member(Action, Possible), + apply_action(Action, FirstCond, Genre, NewCond), + debug(planner(action), '~w', [Action]), + debug(planner(step), '~w ~w ~w', [FirstCond, Action, NewCond]), + plan_(NewCond, Genre, [Cond | Prev], [Action | FirstSoFar], Plan, Order). + +at_goal(Cond) :- + check_goals(Cond, Cond), + !. % green + +check_goals(_, []). +check_goals([goal(Goal)|T], Cond) :- + memberchk(Goal, Cond), + check_goals(T, Cond). +check_goals([H|T], Cond) :- + H \= goal(_), + check_goals(T, Cond). + +possible_actions(Cond, Genre, Possible) :- + findall(Name, possible_action(Cond, Genre, Name), Possible). + +possible_action(Cond, Genre, Name) :- + Genre:action(Name, Act), + action{ pre:Pre, + negpre: NegPre + } :< Act, + maplist(is_in(Cond), Pre), + maplist(not_in(Cond), NegPre). + +is_in(List, Member) :- + memberchk(Member, List). + +not_in(List, Member) :- + \+ memberchk(Member, List). + +:- dynamic q/2. % q(PlanSoFar, CurrentCondition) + +empty_queue :- + retractall(q(_,_)). + +add_queue(PartialPlan, Cond) :- + assertz(q(PartialPlan, Cond)). + +pop_queue(PartialPlan, Cond) :- + once(q(PartialPlan, Cond)), + retractall(q(PartialPlan, Cond)). + +apply_action(Name, Cond, Genre, NewCond) :- + Genre:action(Name, Action), + action{ + add: Add, + remove: Remove + } :< Action, + my_subtract(Cond, Remove, C1), + list_to_ord_set(Add, OrdAdd), + ord_union(C1, OrdAdd, NewCond). + + +my_subtract([], _, []). +my_subtract([H|T], Remove, TOut) :- + memberchk(H, Remove), + !, + my_subtract(T, Remove, TOut). +my_subtract([H|T], Remove, [H|TOut]) :- + my_subtract(T, Remove, TOut). + diff --git a/project.odp b/project.odp new file mode 100644 index 0000000000000000000000000000000000000000..ebedd03b39eadd0019c797e41233d1df5abbe5c9 GIT binary patch literal 52206 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

w#oDxnir`0>cj>Ln)V(ONvaA%5==WDQj_3<(0#Q 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 ThzLuD4g4ek3PGp~_U-=x=e$N@ literal 0 HcmV?d00001 diff --git a/run.pl b/run.pl new file mode 100644 index 0000000..f3401e4 --- /dev/null +++ b/run.pl @@ -0,0 +1,28 @@ +:- module(run, [print_story/0]). +/* + * + * Copyright 2018, Anne Ogborn + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +:-ensure_loaded(talespin). +:-ensure_loaded(anglify). +:-ensure_loaded(fairy). +:-ensure_loaded(snail). + +go(E) :- + snail:init_conditions(S), + story(S, snail, [], Story), + print_term(Story, []), + anglify(Story, E). + +print_story :- + go(E), + writeln(E). diff --git a/snail.pl b/snail.pl new file mode 100644 index 0000000..49c21d2 --- /dev/null +++ b/snail.pl @@ -0,0 +1,322 @@ +/* + * + * Copyright 2018, Anne Ogborn + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +:- module(snail, [action/2, + event/3, + init_conditions/1, + friend_desc/3]). +/** snail stories + * + * These are parables, with different messages + * + * 1) having fun with your friends is more important than accomplishing + * an unimportant goal + * + * 2) when you hurt someone you have to say you're sorry + * + * 3) helping your friends + * + * 4) don't laugh at people because they're different + * someone laughs at someone's difference, and they run away. + * they are told it's wrong, and they hunt down the victim and + * apologize + * + * 5) being sad is part of life. + * someone is sad, and they meet a friend and the friend is nice to + * them and they feel better. + * + * 6) it's OK to ask for help + * Snail finds a rock under their tomato + * plant while they're away. Only beetle is able to move the rock. + * + * + */ +:- discontiguous action/2, event/3, add_event/2. + +:- multifile planner:max_plan_len/2. + +planner:max_plan_len(snail, 12). + +init_conditions([not_inited, goal(has_goals)]). + + /******************************* + * Initialization + *******************************/ + +action(initialize, + action{ + pre: [not_inited], + negpre: [stuck], + add: [has_goals, theme(Message), + loc(tomato), + loc(tomato, ball), + goal(attended_tea_party), + goal(loc(tomato))], + remove: [not_inited], + desc: [theme(Message), start_message(['One day ', $0, ' was invited to a tea party put on by froggy amidst the mushrooms.'])] + }) :- + theme(Message). + + /******************************* + * Movement + *******************************/ + +action(move(A, B), + action{ + pre: [loc(A)], + negpre: [stuck, blocked(B)], % blocked(B) means we know B is blocke + add: [loc(B)], + remove: [loc(A)], + desc: [moveall(A,B)] + }) :- + uroute(A,B). + +% a random friend joins the party +event(move(A, B), + 0.02, + action{ + pre:[], + negpre:[party(C)], % event cant happen if C is in party already + add: [party(C), loc(B)], + remove: [loc(A)], + desc: [join_party(C), moveall(A,B)] + }) :- + can_join_party(C). + + + /******************************* + * The Rock * + *******************************/ + +% a stone blocks the way +% can only happen once +event(move(_,B), + 0.2, + action{ + pre:[], + negpre: [blocked(B), has_been_blocked(stone)], + add: [blocked(B), blocked_by(stone), has_been_blocked(stone)], + remove: [], + desc: [blocked_by(B, stone)] + }). + +action(remove_by_friend(stone), + action{ + pre: [loc(A), blocked(B), blocked_by(stone), party(Friend)], + negpre: [], + add: [helped(Friend)], + remove: [blocked(B), blocked_by(stone), had_adventure], + desc: [unblocked(Friend, stone)] + }) :- + uroute(A,B), + strong(Friend). +action(remove_by_gardner(stone), + action{ + pre: [loc(A), blocked(B), blocked_by(stone), gardener], + negpre: [], + add: [gardener_threw_stone], + remove: [blocked(B), blocked_by(stone)], + desc: [gardener_threw_stone] + }) :- + uroute(A,B). + + /******************************* + * Pomatia's ball * + *******************************/ + +event(move(tomato,NewLoc), + 0.5, + action{ + pre: [loc(tomato), loc(tomato, ball)], + negpre: [carried(ball)], + add: [loc(NewLoc), carried(ball), goal(has_played)], + remove: [loc(tomato), loc(_, ball)], + desc: [take_ball, moveall(tomato, NewLoc)] + }) :- + uroute(tomato, NewLoc). + +action(play_ball, + action{ + pre: [carried(ball)], + negpre: [gardener, has_played], + add: [has_played], + remove: [], + desc: [play_ball] + }). + +% lose the ball in the water +% % crummy event because we're unlikely to play with ball near water +event(play_ball, + 1.0, + action{ + pre:[loc(pond), carried(ball)], + negpre: [has_lost_ball], + add: [has_lost_ball, ball_in_water, goal(carried(ball))], + remove: [carried(ball)], + desc: [lost_ball_in_water] + }). + + +action(recover_ball, + action{ + pre: [loc(pond), ball_in_water], + negpre: [], + add: [carried(ball)], + remove: [ball_in_water], + desc: [recover_ball_from_water] + }). + + /******************************* + * Universal Events * + *******************************/ + + +% we have events that apply any time and don't interfere with the +% original action. +event(OrigAction, + Prob, + action{ + pre: EPre, + negpre: ENegPre, + add: TotalAdd, + remove: TotalRemove, + desc: TotalDesc + }) :- + add_event(Prob, + action{ + pre: EPre, + negpre: ENegPre, + add: EAdd, + remove: ERemove, + desc: EDesc + }), + action(OrigAction, ActionDict), + append(ActionDict.add, EAdd, TotalAdd), + append(ActionDict.remove, ERemove, TotalRemove), + append(ActionDict.desc, EDesc, TotalDesc). + + /******************************* + * The Gardener + *******************************/ + +% the gardener appears. +add_event( + 0.1, + action{ + pre: [], + negpre: [gardener], + add: [gardener, had_adventure], + remove: [], + desc: [gardener_appears] + }). + +% the gardener leaves +add_event( + 0.1, + action{ + pre: [gardener], + negpre: [], + add: [], + remove: [gardener], + desc: [gardener_leaves] + }). + + /******************************* + * The tea party + *******************************/ + +action(tea_party, + action{ + pre: [loc(mushrooms)], + negpre: [], + add: [attended_tea_party], + remove: [], + desc: [attended_tea_party] + }). + +theme(help). % Friends help each other +% theme(friends_before_things). +% theme(friends_before_activities). +% theme(apologizing). + + /******************************* + * Routes around the garden * + * Places Pomatia and friends * + * go in their garden world * + *******************************/ + +route(tomato, sidewalk). +route(tomato, weed). +route(sidewalk, weed). +route(sidewalk, pond). +route(pond, ants). +route(mushrooms, pond). + +place_desc(tomato, 'Pomatia\'s cozy tomato plant', + 'Pomatia\'s home, a sturdy tomato plant in a shady part of the garden'). +place_desc(sidewalk, 'the garden path', + 'the brick path that wound through the garden'). +place_desc(weed, 'the large weed', + 'a large weed that Mrs. Cratchet never seemed to pull'). +place_desc(pond, 'the ornamental pond', + 'a nice ornamental pond, with a little fountain, and lily pads that Froggy loved'). +place_desc(ants, 'the anthill', + 'a large anthill in a corner of the garden, home to the busy ants'). +place_desc(mushrooms, 'the mushrooms', + 'a large group of mushrooms under a willow tree, where Mr. Froggy lived'). + +uroute(A,B) :- route(A,B). +uroute(A,B) :- route(B,A). + + /******************************* + * Friends * + * + * Pomatia's friends. Pomatia * + * froggy, and Mrs. Cratchet * + * handled special * + *******************************/ + + +% only friends who can join the party +friend(beetle). +friend(grasshopper). +friend(worm). +friend(ladybug). +can_join_party(X) :- member(X, [beetle, grasshopper, worm, ladybug]). + +friend_desc(beetle, 'Beetle', + 'Beetle, a large and iridescent blue-green beetle'). +friend_desc(grasshopper, 'Hopper', + 'Hopper, a rather nervous grasshopper'). +friend_desc(worm, 'Wormy', + 'Wormy, a nice chubby, jolly earthworm'). +friend_desc(ladybug, 'Miss Priscilla', + 'Miss Priscilla, a very dainty (and quite fashionable) ladybug'). +friend_desc(cratchet, 'Mrs. Cratchet came back out to the garden.', + 'Suddenly old Mrs. Cratchet, who owned the garden, appeared! All the creatures were afraid of Ms. Cratchet, who threw stones at them.'). + +strong(beetle). +strong(worm). + + % use botanicula for friend can help ideas + % spiders make ropes, beetles move heavy things + % grasshoppers jump + % ladybug has no 'special powers' but is good at emotional work + + +% make the child a rock saver - 'but I'm little', 'to us you are big' +% it could rain +% don't forget emotional action is action +% has a tummy ache that turns out to be an egg(??) +% Pomatia loses their ball in the lily pond. + +% Pomatia could find lose their ball in the pond diff --git a/snailgarden.graphml b/snailgarden.graphml new file mode 100644 index 0000000..b9bd0f7 --- /dev/null +++ b/snailgarden.graphml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + Tomato Plant +(Snail's home) + + + + + + + + + + + + + + + + + + The sidewalk + + + + + + + + + + + + + + + + + + The big +weed + + + + + + + + + + + + + + + + + + The celery +(a food snail likes) + + + + + + + + + + + + + + + + + + the ornamental +pond + + + + + + + + + + + + + + + + + + the ants + + + + + + + + + + + + + + + + + + The mushrooms +(picnic location) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/states.graphml b/states.graphml new file mode 100644 index 0000000..f70ee92 --- /dev/null +++ b/states.graphml @@ -0,0 +1,633 @@ + + + + + + + + + + + + + + + + + + + + + + + + Horizontal Swim Lanes + start + + + + + + + layer 1 + + + + + + + layer 2 + + + + + + + layer 3 + + + + + + + layer 4 + + + + + + + layer 5 + + + + + + + layer 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Start State + + + + + + + + + + + + + + + + + + at_grannys + + + + + + + + + + + + + + + + + + at_grannys + + + + + + + + + + + + + + + + + + at_home + + + + + + + + + + + + + + + + + + at_home + + + + + + + + + + + + + + + + + + at_home + + + + + + + + + + + + + + + + + + at_home + + + + + + + + + + + + + + + + + + at_home + + + + + + + + + + + + + + + + + + happy_granny + + + + + + + + + + + + + + + + + + happy_granny + + + + + + + + + + + + + + + + + + has_pie + + + + + + + + + + + + + + + + + + in_woods + + + + + + + + + + + + + + + + + + in_woods + + + + + + + + + + + + + + + + + + in_woods + + + + + + + + + + + + + + + + + + in_woods + + + + + + + + + + + + + + + + + + in_woods + + + + + + + + + + + + + + + + + + in_woods + + + + + + + + + + + + + + + + + + + + + + + walk_to_woods + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/states.png b/states.png new file mode 100644 index 0000000000000000000000000000000000000000..ca8d2147c7326a87b432b55a94a5523e76d008d9 GIT binary patch literal 33693 zcmaI81z23c(k+Sv4;Ews1PFtL07LNL?oI@kAcMPmfM6kbaCZpq4#C|aI0SchzZ=Lo z|GV$r_xATOkeS}QyQ{0KR;^x>0C`z4bW}oA7#J9I32|XX7#KJZ@RNcJ2fUMQ+cg3M z^A$!ySm2}M^o|CKIvmMzN2Wp|I5SI zIl}S^3JSOgnDV%|?c|Kx6#)TjEZtOf-R@JjrPuoG*PkpRzA*LuXnkjJp0{v)NNeou zT)U8W)%0s?%lwFx;_>=~1B)R3a9LtM{<|9a#lxlk4CUd1czt`go`D1efy*oKH5qU< zi-bO0f5DIU{r}zg?>@niuYp*PPbZ;3ukAYbxW@$M{rk&r5#Se0HS)tN2o`wx3%105 zd`JBm@at)c7EYk?Z;^5kfm)q`(~Mj^tAYINP+&!srt9%UG~Z3xVY45H#r`JtG}=SEzu>QX z8p79p)6=^%YAS9g?dQIZq7TD)J|bf6fPZ0o!ph2;>9H{1AZJ|GAR^}M>oYoJYHCV% z+8%{@;Izs+MU3dM{{?Ekw?RP|&*>R-addWkFcm$jm29GKw!69;QKH?gvkbra)Y5tdq0Teis97^uldx**9zn zK{4tpg{sh`Ys{#$qt=HxvZ=59Eg5AAk5bY|C5ybvbn3>EW84Zo<1f&1icRIZ(L&f{iww#ADC?|MIKR$~msdVaq3?)q;?a!qxu+j*5%rg~e` z2T-k?^K-c*k3>%Q(uM|j9-j~EdF_-ZbgJ9nqX8*cKHNxF_MM$)*WZI1FV>2pi`bnV zHpFj#-1>8N#>d<6-EA>2cwA858eVkieRQuzR(~ch7a1NsiEfyDC2v&Y=wb}RawqA2 zd$U@rBq~bSYiObIDiLod!o8t#k>^m%%H zBs@WC>ln6V2(G*i3>kiIhh~f^BGzL#h9BQE7Q0E`sitH;i*tXyXyB1Xsbn!9O^2QA zWz4J^zMlD&6qWM@r@Xb|4FfTo!t_*qMMXd9MlpgNi3|w@&d`Ytj5Rs>hKgX=Fkl55 z9wE-;;JEwengwe#xU5>ZnRj#I{$#XCf3J8oDcS9EouG`l-iW z$4I$~kY9-2y~gbt)R>;dW@)E=;||`4>em7cXK_kwjHkEUXLaLEFg>R7Jk1-4Mz3SV zdYjZCg(xz&^>3aJ$QHl4y6Jlt@A1uiIMMMvB^<8ErE9K<7a(w{*S;u z>165(Qe$gKp?P@p(1hva(&A>j`B}e~N9tw8lv;Z|E#k<64fNH&MIkxt3ls#38gJQ*t-yKL7P#A#IeJH$l;!FcD3=MSm%5(D zXJutANnym@$vLGPzVlqSrsWUpUP8w}f%wo3-q{RUH z5c~L-Y2B(;8xe(;Ex7=NjGmm{$GhUIht8#6oR z^SwrcdjWm*jIEx2E1Ya+XQxrE?1nqdhU*==_pfUNmc23i`}&d^FGSUkRxT&l*eaL0 z!K}6Z(%*3tCTJaGJHZOKh~-tKrN!kL1jZCHXs={}U31P}Rg8s7>=z=P)r$SJ$^MUk z{2hqc{{l7;aenQqO8Zn`1@(aDY(r5@`({tv@%U-^P3vG2ya>#L zC&2Wz78!5toA*sI8k-seAw9Y(Br);po9J(XVzq7y8!_c5AAmrtUU$lS@$4^HvgRp4 ztw$hgtaOa>RS|DZW5T=%5W-_ur0Tb~J0DRcKiS*h%V?Y`tCh2tQ3^-b3Uz7 z2z#-Ma^CabBI2&I;?i#dLMT3nvV4($AAtI$hZv!tETWkAcEW<8{^~E~%H!02Ylmtn z#=d*oU)m74gtfmeK}8WdC)Hg5K1%btk(au&k)v@{YBklWi{9x1>*@sfZQyC@7%;rz zaTis%WEF>hOfQA&ZfC{iD2=)ZShq|aMzTViN<;P3N9=M6+*C@xz;yPl7!V>wav&8ut?caC;~OISBlb<*{=QHp{cA0)5nreBwm{TU^QfIm2u_4O4iu8pc+ar{|LAB2 z)pr{+eR%QtW;+==Q4?$DQouA;iiq|=^v+Ofx}UMTt`E^DW`V&Xl)-m{m*KfsUG4>OAx4;a<7Q` zC1qqN-s3aOUh8hgD=H{!3!#2C-dw6tg)|uqhH3Wb>x`J+o(cM+JsJ$k@Qor@}ewBTv;gxAlHWu+o*-UtoYI9ZXi`$hh_Pa-eZ6$Q2d46IVxT+4z)>kja!awyH zk=u}b8HqRt`|u3fe~oE9%W)Sw(Uy)OyQ~U-LZPY$mdI7ZF~<`u5w+$4*wX zF9HQ6fpW*Oak25su)&YkC`ZXQA)TH=qa>XfXi)H{AR#d*Jok_AQ$kXI{j}9jd&%Ym z$tjfd##d~n1eI}%uIK9iqbPA>z%g3IN1Xe`Yv` zhaDCe|K8U;wvz$v3!{r|S>Q8!Ore5DPv=+BTgQ`Xq!YemPqW#A3 zo8X1HZ^{byxa07D;{wZFt>VMN!hSb1>P{h6Bc~7o8#PKju3Zi73z-wUOUDSi0uM}M zpW$LHatf2PSm*a;s0zk{hTe=96eJ;;_>&d)cP^Y>#d_8d%_N{Tt0XxzoZ5MKsf8!7`E_e!4y$L>!GB_vYuHWhL zzM@`e1?-=4GQwjubaMRh?SQI^B;TqMQwb$$5>-0V3nVoi6A@8#!&<+vtldC=KmV5m z-4~KG9%-v=_l-hq8O#h~B~_FkaJm<^A~^-R9h4WT?7x;xh^SHl!-AtohA&#lJay;k zuAhkEt@9G#XZNtK_UZJp61zEfzE4B$y1*lhc&4)!HmRpGTi##fpyq%sY-7;*3%;r$-?77?9@%j(anOY*SUFLMv+`%E6mhsiT3nZ6L~Ls(XIqrdXliZOY~ zqN{gOXRU>4ZOLUwi{fuTPwbU!P*Sx40%LPkY08q)xaOhd)+32+B~-W=m!3eh;x%jV)dKQglq1G0>~ z1Pn&4e^9~So@=e)9~D7!J{@w#e2zxO#)u%;kH5ouW|sV?+Qp_izX_jf@2#Ye#ry6L z4zO!<;!m<%3+t0GW4tpHt5@$Dpe)r8-l8?WM9DR~bMw3OPXf(-DkkNK$QwhE_z{>I^60-F%=>fcEIJ)zFV-`nGEXB z91&WsPC%Xg$6ObC;JRqGx-KA=0-N$7Za5-@D`tORUW-v~tP@wB0Jh|ysyDDD&*tq` z3*aDdZ$#ZCGFLLO@uE7c5l?;k@d3QL2c%wL>j6);$c39mzK1j~ZPYk|Jv8*BkC~4o zY)#>S&>{e8R{I4bqwQp$R4s~P8bic-QNt;9#PP#PWHsj{ObE2xQsbE+S|P8akpTlP z($JjLkQXlUr{yItg!ON`iliAkPF}Hw)7!{hxkW3 zzvEgzJk89S!J8`A(}4VX_FErhWp&JLcM2bOc(51q!P2xhi98Xmwi(#le{FY#x+gx# z5HypcU1o+k$$x(jM7G5!yRXX-9jLkHb+eQ)g*}`f5DG@Q>49#H)sLh;G)p#CcOB6* z)&22DXoNY}Xe*MEx7V~<`!2J?6drzzK2LnR2<9hJaJxSazJp!THvS?y&)4II7Unw4 zd0l8%zkv0(G0>EO4u_K?P<<9N;aBE8hNQS=bR8)KuAJEKt+{e#)zTnBIKwah^pq*V zSFc3yPURHPVP@+v02k;aia!@W>yOZh=|xN^$1)DZZf>gU$I5egN@4IXL^CA_yAKR8 zg2fvfPq@%hjZ{0B#4#VUtg|_3SbcnAjp|S&N?k%pXtsWzUZUO>F)`Y|1V|*wFo#o9 zEzzNZiH+l0b68B*ttK?-@|>24*K6Z3$>rbxgQ*6_QbP-`^v@=SHedZjk(mgHc8gLWgs(Ra|xQ;@MMoGu4jkPCXe@ z^hlHtK>#9=1W9dN=pG7h`Y7*U=|R_s97n*9nZC9S*w6rMz)_*$4ga~iVQP5vftW^< z+KnOgJ-Vbguf{dj5$t2f zhO=-0i}AEvzwimbz(w?7j$Rtvmp}aSmf>wztUB~34ql7;xKaXG*VlAj1MdC_zJ?OE zev3uRNQzH;4Q#M4!ou$YQ1pH2%EXwXH&pt>!8k8sj*1KW*p9M(sZwDUVQi|H$ge;8 z&bzLT-}9Nk4x!^@Ywnv(Fr-zftRf7L0XJTFay~gwYOVi@^u+v#R4gqU`pfW~8yJyG zVL#$A4*Y@vnzv0sdt&`1vj2m~(oJ$Brwx@4?hc7(3zQyYFe&~W4uz$5{b(!*lGSav;eSnrcr zHo(*t9`p7&CVc!vjJ7*tD!pu@eSMikGW~s8T8%#a)EUzH><4FP%5~W%U8f-!f4GB5 zxhUBfWh8monq1Yw3izv8vgHZdJEePf{?PtPNectNVX^KzL3sNrzCKYrvaE^AzC%#8 z`h1qSTM*SnOySR(SNbVwlg-+n-)$d*6oWW1Ut$3aO{wzbS#wTx7|Uq-;MXvmQK57l zBVH!^3nDIzirI^yNNT|_6Dd$^qoa32`tch4`p=KEQ*+z9x=NF-dtt@~4iiLg3ZK>hQlw$F`1(I@eQ`3|f5H5D*e|e|-S@ulHCzw7Rvj3|WxII4-B@SFM{e&SU#PByQo;XX-oK_A?!0Osd^!j@s%`WXPb% zn=_?(hx0=hv(Hg|TCoW=(>)zga~FnlWvRN^(;V*=hkiH~=6>p=vY=L6m1$DGw^BcP zMoYxS^pa|Bi-M}Ws9m_myP?_GrxC54?hm_3Zmyjw9q-IK&9Y!c-$K- zkXYkH66)1$)iKC;Ma)x+Lc;u)1izpB1S$=thKMgIUQgy(zk z_90YI3HJMpqCRY?&(6mj^yS6nsxb{nK=X*TqSDfm#0pd9$oTPF!#QSS`Yh<0N<7+c z%!kta4catWrl~TrmnEn1$7quRY5)mh8^v#NVSg~wz$7+*c%uRsg6IdBriXBOaF@zr4tVLx6?{A zdvPskp&KgOp&!=4(V$x++L_^l2_fxP9=gJ4dhB#WP*poepm4?Jsxmm$9v0j#=bg{!lv@JLS+F zzVgY0s;R<7_Y0*t*mLh;U0bS<6_xG>8ryrBTXA%rK?Ik`z=vUaJ;VTphfS-mHQgQYA1b8cHJ3g%cUk!0)3|j+)23qhiexLP0-EVnl@C8e{E)^@5cI2( zK~3>VOkIDC)SQArf`DrDwm>f@|8=0wIK2@+o+P`CsmW;e}X5H92YAeR*kyrflH zW}>qN@k zn(g5i{8J*~S788muta6du6OYp9z@D7xq)#oEaHFj3^WXfu`6YR%@i@v#6qa~2D=DL zgL`;#eEdu2p(--!94v1watF9pHMGn|S4+%Oz+OZxO%J{Vq`c%K{?t*qwGjXEC_59U zvwznp6Xe?qfP`R4i7_bjAi5HCfSC{}7M1dTZ*x3QKI|1L+Xp8(05oBF?_3)flAMSV z`80XMEOzIDw~!G!-tgGZYszo17u1Hxe{wl_rl zd)%(t|LtU*fnq3whY$+F?vELie22*K$23em7SKlBbP$JVcyF!VbKeEaPMB72~;26uhxQ)?P#e0#Kz z0WM7wQ`6G*lm3+AE&{32MX*_0;}UyoEukx}wsA(By*_R6a%;%1I8rOox zieqb_#IaJ1%XM6=TD8-)tVX$Ja}c>DHf4#vuB357vmYiaiL`d;en$)QkjBC<&nypr z>RR1QhR;{ONYO@xlw>-UGYDFJ?c8;_=vr{*79Tu9_e35vPLe`Fz-#DifN*F} zi4Ua!E1wD7-f(x5$}z?=(w@chAF`B`raW({IR ziI8Tr?FzQmZscP3!B+j%czca86)NjG>)${h8z+AExrhX`7_jH+5Y~dW-zqW|tl5lT z^?mFwSb}jy1YtB|qDl73KDy+#egfIWMDWg$a|c*E5&lnnW6pbyHaS@ ztl;;GvX~N1ehGpdQvy}8G4)xWljGWRtkOiPq57KsN6^5gr=nXrbRwK*VuGa-lqJHDK#!!!G zSO=iwU+|V!dP;8cq$mixN&9r4-9NMD$8Mf|csZFg)R01jGvIj$^oYj0+b2C`~z5TQxP;N9OYAL?AuUM2G0xag`9ypUdsi=n*$b5g-cDb}2d#2|ysR?;~0&@g< zU5qWmlm;S4&1r&=`NkP>u=&QAj`3JFE~;4vlAx- z+vC@f^0zZ(N{_>dx|JJ@CGbbaICYMZ*6a_jZ7tFRvj!ZQ^-+e(4KPJdMS}dPN=jMC8(&b(9|zNk9#T`s-rl7CtjEv( zkJ|#NC8J*xY-_)b!)1ExiE4G(9M`!sw_}O@DX9}Qk!l+erM{9r+9yW(O7{penCa4B zwaKM+t9~LbN_Y4dBs74*D3k&lXaJX{1ohid^inydB!+B=yT~f7Npv$ zVUf4TFX^Rcuo*yEMJe_CORTCNXHOXW^NuJc42OyB56RY`6q6wd-Je1N4}={W>->X$ zf7zJKb&*~82)#pvq)|X+x1)KG27iY-W{h-goJ4XACBj$T@jF!ev)D(Dw^L=Ih!l2o zP&rCP))qr=w{c!*lk_8Rk+k_mFKia<)mmdGZ45YoP(lLa#ABT|ws2}?hFAH9JhB<) zVL(RY^X}(~{@OupaJhO|_($6f_He1AcRklb8eG1^rQsVHzYfG629+6k`e2>GWWx*F z^IYe!cxv^Gpf`o?dIq{_QEEuf^IB=YAzNHTl!T87Yi`anx53wbn7eMLCPzNlp10!;QrK0FjF{n?j2TQ_$rhzf?OH7m0zC{H$i88p z(@)lHFqLR4X8TN2CQI}kqxTvfK6}3b7XIQDn1faZV%P>5_YA5WMcdu&@e(Vo;0pn> z(58a}DKw}N5|Y&0I>YGLo6(*a2c^F;XG!V}hl5^B&~LJHan^_22q4!q66vIP0s@^5zknl# zZ8&wFdJuHqbK?ooj5%M6Cnp_`N^>-|F&k@31LaN^`V-FRe{Xr{X+gb^D}k@R8|&`Y zAmsS*W0j_Y*mjbD`4hz6>I7=jhO{(Y@&b=v%c^gj92sXBUcX^uEC4Kl{O>v5Cj5RB z*@*U~cULd`lIESknk!qLV*3J*V;_D&)u*uqHoiZ24-%9(%Y6O#-Dj1XM!|ezgnbC(lNZWB)MH0_D%6If+f%H%mlH+ok=Qp* zg*)$AY9Z<@qOWZUdF*(TtYM$*u}{UxiDb7=vf}FOm)JO`c5o|mo)9FlH%}}C)_E8C zua!s1I~Td=y)WP}w+`Iobv&wCbntzxfu;uMYo{HoY0OM3;bxb2uus!-{zlwsg45Y# z&VYM{ddgkh4ICB{*Hh|@A1%7WY9y-jC_?Gzatyz{d0MRJ`-G+d88MWj%;hPgY8@SJ z#>>D^F=~i;((v7UhP?xwfOn{;qjLYRu&v+|*0h8zmwFEr_y>1FrU++{!nBL(-=``X z<|L&S*DP1(>~nIvA*w$KCaOHX@o!Mz)`&irj%jpk^$f)1e{yPU3>_tvxtmj`L*48P zTh#LM@*R?;`0!cXy*^$Od>>P-ndOUtuQo1jBudq;PTkTsS2dWl8vBWRikeu;C-y69 zCgf3iXHv;i3|4wSJ@~)+WPZv{NorNh9vxuFVtA?=4$%Bek_&tJcul6(eiEP=3HuYU zu~C4jiVaAql`yB9DViv!M{N%eQdd(IN^IlX4vR*2N0ru0>A1bui=UPl7C2RXSf#Iq zaF0v+Iu7Q+WGTkrr$2s+$mhK#cyb$VEn0I9^MF*Y+?i~w6rBgPf43&n9%45 zf3f&>1j-OrzpI|_;_lQ6puwl|y1Yfi^clt`txa2aLfnz+OC-xB3EH87!9anVblxvx>G!(AfsJO)bx%fFK5#D!X&^ zjmnaP=l#`=7Y{L+Q{z#`6>u!!4Y6L{OrF88+eI3Ba~7o;{!5vPY8PPTo-xmgE_Tz> z+ZE+_ph7R;0mhci76moz2Nk?8g%{4h;eDUq5$=IDD*GYaVez{-W!?sF=`{;S5- z-3~^kJA%t}|<0J)s*3~-9I zj_Vwge=%kM)DLcHy4~9p!#*5mn+XD^+ZkiIe?2Yye-JP^-#kC~ckn9PTml@z{Dyxr zK0g~_QhmMUrTpT&k6IaZp$2~48y=k_<)(7skeqjQ2ij;BRrdEjM#7jgcMXY(I9#$4 z+a<3X7N#R<;>!$n+|CQWJI@OLt9~sU_cgnlBTev633&Pcf+DD6dvcA<$A6NjsJlQy%tz(Q_x;ng(kgRaB43NXs4Fd@;IU2 zc&fiz+8fue(Yb6C4MO%`PLGe(@&q75b;MLKF4Ml>tZT*}12+57bTnkE%RdQmIeU&JOn-@gT8^wA}H!Z>1=f(?xFZW}kVin2unOu;6j*sMxE5 zwv&Ig8@%w`?lF;)u&+Jqp_Oi&!_0Nk+mlbxa%2O7%e-Gmw%H2m0GWgE6C07XUwwHp zQyPAmi*g1>6i(QAf>rTKIO9NyoTJJ6c?gxDr;)Mb^UpwNSe*?EUd}zwK#C zy622ry$WlYh>j^NDI2ogF=@3VB7a()hC2URsJnp}YyOB8g=>{VD>>vD#Lc->$AbGOV-@>owS!+_=G$iO$lUI=er zn!C3@dH9<-;n_qPF{<`YY_88}{?)=n)PdAB$gvXZT7>8fKmC>bAxVZidsN(tPDEb+ zqW8R4LW5d5F#_Tgo>@RRdYgcD00{h$Jw~1(VE*(CEGMo?a&NS6O!o8Vre79(^F={R z9RB;|bb{*!a56$tBfeT-5O%wqpKm7E0uJmcqS3{(46F1F_X~mkD8bxpqf1$le)C1Z zJ3Tu7aywQkh3T;rZWRq7jbyt$Y8YhO=cTi@>Sf6N7HEij>R_@A?q4F0HPR3Ed2!f) zz*DFCoRk$cP#~4-HyX&w5;w8wk}RIjvi9@J(w+I#r)vK-Di$h=>C6s-1J+NJMRlS+ zC|L%N#XL#1e{79Yzl)at{hVEKi^7U^#u1ykFwSHR8MrIDtU)0+DL1c7MpJ=9__6lR zFxbzTb)%*L`1L&ptK)BhImCF>(Y462@s;mMC6zy}$G_)7lbhgusIUK)2Fjyt;t`O4 ziYYOLR~PQz=GxahIA(b}^*b7jO$aq|ioYG#^!dGhn7$M2%utX>y8nUMJ<_qH+ z#dlU~t`Dri1K(h`GmT3$B2h$Ip3UK^B&43O+h%hAAI$S-@oaS6v$12gT0w;sH{X7P zi23C|SfYSHd7X`PdBpxxerTY&p+ROd(`D$1f)dYT1ZTN5OKOVYd`I}u0LTk`AI6*? z_>zF2S%k$C?UMx;sv{>e#E!@_D2UZVGXiPuGMB69zsdmr=`h}T-Amj?faZ`mK|sbBiz;M3?L_{E2nR-r#Dxcm-{K_ZVeKE;=h z)1hrYzY}@rRdG00&KF5x0Vr6UU@dC}{wFWDj3_1rMrGTd?>`8C&z{r9uDETJqU)U* zuBi=R=xyI*(Hl)S`aAjqG|moBpl%x%t$!75$vblFW|=`$Q>4_9Q)_2@TO}&XUR-fh_oS7O?3ljjPd{e0Gz^`;;L?L8 zLi<>XUWEWBu>Ta@}kY%AUE#oV~x~f4ep@MQ3F+tQ%ToTh*R6<-hQq*CK!_vI^?`n$6YJ7*j zH?M6PcKlEMpYGLDKc2V`VWQVnDe8(z{}j|gMMa&rfEMIGpc(-WQt*!IVJ)lk>-w$P zHeYFk+S{f~14^BfJG5;ZMDK?jZOQkC~PI{I)nm_NaR?Rk3CeSyU*0O%d?&%{?fVE zlH6wSZ8dPbyB62ew9gX#YNl;xs^y1Dt4#%eO$8?!qFhW3Ol{t<2rp;9>q#>s)&1W$ z5gwoK>Ij+kE3#IVSz2Y4yXkNlE_L%F9D|}z-yVN{sGb2KR;kDA)vk}y{5??8L-hIx zLwUrc@~(|uZT`(_zHKV=s&Sv`Nc=%ST*l1>(0}OM!+@7r?=G^>p!EW35NEpsq9|@i z(T4Qg^8Q1N`a^F+O<{P^J+mAW$(@`;Ub3jS_+I9=2jIr28K7zDLDwjoQ$d&vO`~3W zz6ePh!P{V&9FL=0E-{90CtI}ERz!Sm?w1u}me`RBw)tJ zi!pB7u-Iajl`u|~gy403N7ya(Gy6jqK;Um)FzpR68Hi6TsfupS3XJK$G&_stNoAOK$@2JOmC#f z7lgW_C%g;Hb}pC;V4qUU%0*@!d51J^O*KJ$%->t^mWXgnmGL%kX4Q@+M)^Z>IdZST z*-_Bp*L7$c?lV};YVjt4)(+VOyUTe4+xTBIq@y07f({({G4Cq-{a|FaHJdk=*Ti96 zQx!QkgikbeThH{`QX*()aDwMQr5SfV$RNn?OQ^I^8V z5FK4w?S1z0%96UF3yEDM1{s-tfPriY|CD#_6L)A6bu&Yh*uZtQhWpC2B zMmar`cU<_ScErBV`-8eQuS#t?TkgD~%#pq6u*l_efCP$b9T;xTsgO%fV`b8Zt1%JY z2)b}+%q~ZYB&Go9BrUO7)6(u9poa`^Q(E_*od7@%@oV1$V-CPL(Jm8_+`=0fa6n}t zB3Q=o>*9r^vFwlXG7!nHYFMDf1MJU1vH{WW5w!#c99dXAb9TJUU(iGz{`VPlF=>0-^WgH!++dT`mDV_3Sb;e}OY3+$T!lsW1V0fcz6MJsV$DviZA;Cf zP_p;<)zrEy4Fd?|;aIEu+e!YX!hu~39yslB@@RNHE0!ew`Wm=F&Ocb2@~0suLoFa9Cm ztlsGSUcAYf0pj%&p@L?0d6}1t!YfO@@$mnS%X)Q&GRC?g1OIr3h5gzB^`x!8Z{iY? ze6rR5f%m$A;FLWcXL}o-2X$6|W^WPYWQD`DvD#t}7gKzStkk$G-8G z9(yV;0?x||(41|AB^0_LD?APIrLxb1^mwO!sVj!;?5q-})1H2AesML^o^aQbH-9HA zIpQ4?&A@brxx66L42loniVqfkUMlE+TrL%pR6)hbCZN6lcWsXw%EX~d%n%#^Xr=)e^@D`3wMokI z`fOLoQxlL7Rw zyi!Cuang5C+xxG-`Fqbkd(O22h%+lu%V`w!50D}|qy>v8> zZGnTWX~;oi;hrW&F!)d?&PZ;wH4mOXh3K|IyDnZ*NSC#t0y^26`l4iOK$ zYaj0NT?hYHhhVeWzrGU&9PW$Ke#?z@0@%88^oj=(n#@f%ZcK6mxI0YX8L= zI43L~t z$gh+a8(g{484csiXo=LK%p5GVu%23|R|`>F-E8NdRa?OV7KAZv6;TbkIYM-Pi68YD zV6)OF4GHUdwv;O=Ed-y*S2eS#w|&+424;E7=Dvf=0>Aqjptm4SaE| z-F9gJk(|@C#SIC2up@BjVa8kAHFXtNK-AeMzCBcymuu(p0=w^xMwC!v4*0%if{L4# znvy7H8fzp#xq^KU51jCx*V$~(p0|n<@V{oZs;RZGz@abD!{+==8b~l)R(vse;3nv1 zcIb1%>S8u$)^-VSl7zzg0;QiymL$%hK2FKo`SDKD$u*zApGwgM8id%><87Tm*y+1G z2zbu;z1dg>saB3TE`Q=8fkm{c4)O#Xywa(iEm|XE=j?dNVf2IVG@7Zn@vG%^)hKn; zCYJDHuC4>arPqeh39tG~>>w7>33$6qJCC$U$(G{9)r-+EY?PTG z@!<82AiKw=^QHX)APzOHGN$y1^sjn@!+-VkX9P@EysX+J3>iIEjawUpQGnS_u5rvH zSci>PCGY-M)F7T+^-F4L(Q1UfEyLvNOjgSWM28^k$4yzuu>v-zL=URmSZbwfW42=cfWDXyE0~M{S{a4n&V*z~}V{tz* zh^Fq=b-kl87|wg=eYtQqq7Fmx*v!Pl*9ZGFR|ae7d92<7f-)Pl-Xu4qy|;O2$SCYp zrgFz3(f27{fj`-K-N@6^A4wLk1G+7=+?%!7?S(&e?MF{N6xe_^LCH7MeImdH$m)Om zUJaM-Vk)iNQm3rK!Anagi1pf9qER{mSz^qpc>;D4LO~B8idi-=*pg$0fAA=8vj$6S zE~HK&rR1UKtS@R|E3o1i-n*!6?EHBPqG|e!2QtDZ?UshKmUcXpJRpHxD`^$oXcd%r zbcxA7AP^%fD{a2BTo1{EIIK6)0h{yY6<-U4b>M5!R~n~CI;Js*zG&6}()GU~GeBNo zy=VmFfWIEJXBJH`tH8GyrZoi`6Lz`8PstNR{+QSkkA9K*H##2cFua*S?-p<-L)3E_ z&GJKHpu&2RT;LN8pbe&RF0@Ik$jhh3gZ`P7E&KD;=dmP!Ed!Vr(4tCyyzW$mi^HxQ z_#y5BPLZviQGd7@^FD7X{gRS9(9>;4R3@%ql}7hzPHR5{O0FV8KWu;E+;a*3HL44g9#9|Uf*Rh%s!^M}W%ZE_NZP3J`s}xqy~JMU0g_2j<$t<# z0Fjl3*9Xld0(rny0b!9~mX68p@Ziti;}Vmi$E^z3q_FTDh3bn&{6GSS`h2eiZSm-A zVBZ;D6Ag66GPT3Gg{Shg20PW92s~436&60thanfgxw2%gXDWRk^om7isuKQ)EqEJ{ zEByucBR@ZyQ+5;;qBra9z-65AC5j(&e0SAtuQs5OOccgj*5B|q9a3qx3*=y2OVMySOi+Ry}HdZG_@yoxkF-YxGr}-bjV~;!zhb4eI9lAaUUo z&X=Uar1hCG!_CgKn~z?%r=8m%i;?2PKcYw8YW;`V3(9qN1>+-$kbyqNA@Zpv$@ZwM zWYgZfvv3JdMW*qvZh9G_k$~U6)yUmbyLzMQYwO&J-KTE-TsP;$P$E)x9Sf-}s_>@q zJa9o{XmuSEoyx1p^2fST1^A0Uk67z z({L5!>X?PdV{^o?LBr}wqGuMUKB&QBYt6lMN|xdXM0IDx2|1}ze`qHK`|Q=!h1X&w zb>>aJX;daRCFEYYc=Qg+nN4e-J{L`7`1NuqsVy$n8ja@9fbqyr`u~VY%&yCh^{&M6 zmgC$@3##K96lr3&x>lm7j0Zg$WKorHXrO#`>?U@;7R@|* z>%ZNTy{>1$;Ka>@sR^y|5~_9Y8fQ<5_f?Ifm@%^oQ|kFx5s`uZg{gdzK2g|LjQR3s z^GeGAG^w3wSo0-qa-Se-To|1Jrmuah!=pOIXsjsNl(rCB^ieX4lc^?ib5JRsb2{9~ zrfdyR92gOPRvZfB*+sJnFk21y#KF{slldu3z-PMfaT|3KX-da6^~}vo^v$;P&p2$Q zouZn*3PY7+BA_KOs>Qs zt%4f88Kl<_SD7qLxNX0tlva{86uW77IjXo@e-dG~nm0wee%^lHv+_A9Kir9MZbR$L6wFCERaXE zCRS{vF7&w(#S4?)h3#p}oq*!STgGYCz&h5b$78|i6o=7(l6fK1#nFcCIGr9-dj7Ed zkBA17;M7pkI|32<}dF>Oi! zu}yCI+yB|zcv>0#OX1Xjgb(9oQmMVeW`M8Us@W?N@zV7i z8@HvBSb84qu!~KGTN9iR(|A6c7&Y_F78-?VJS_rH?wn4H$7DS_PR;M3yKUL) zF$lqEokqXXy0|h@_5|Ww7-!>7i}E_ylwbjzcQjtzZ%w(TvXL>k)OctDRAEK3`3|>cFyK1tDc=mGV)0P)N=3emYE}ouvm1V8Rh|0 zBhFj_UxDk{(!m-123FG5jZkXT`sQB#UjY#4u6>*zDBt?gFIE0QUEq6hj?%7zJ!20z z)9gFs-t&$NC~w>MHTLngrlMHGW`EEAzy|Pu@#5T=wpzUD`SU}VnV-AvhuzvUSW|z3 z0+m%&Nb{Zg?rwn9bx8gNs&RU2ANGl(rolVtlI}(>NLDbcSIrM%n40+nX(}7}2$C8W zLW6&O&m$!%xUWvk&D8 z?L?HU?NX|p(>gNMJM#TUM#RzoUm1}}_J2Cktm_)UnW(>oGlT-7Gy?|)&!NpAVn3}- za5)b4lfp`oL)93SnvR-fgv zsr^HPHbWvYoiBGdsb0jnDYSzY2Z;%wOSP);ttK^9Zt&75D?uw1#QF{>hP^Q2|KUj+OS%@`fZnQz z{V@u(!ZY&5#(6UCx4+bia?T0|D8LKuLg6 zCVTRBee6Fp$*%EDqlBG;gS9x~bRxQ%+_gWzF)Yt7i&W}=b@tX_RdrvxFbL8hB`F}A zQlwj2X(=h`?$~s9No`W3OS+_C)7{-&(hbtmXMxZ2d(Zn`=eoY{ob6w-=3H~k8gq<$ z-eauXxoh$NnAxTAOiuZbyu0=_4a}xLDP;!JK`E(qYRpId$JS=YPoI&uZ_>{ll3U5hHAKj{F1egb;bLlIe9cs9oTh2$;JP&M zkJ+BY&?aL!qz0Xp(Md|({PTzo-iL%mybRHBsJGUt$~X9rTtRV%om3G{c(Wu6Kc?Hq z9!%{uYfM4~x7h&d?STO7$1qf?r(NJ~l;p<%B8_##*j?i5xjMt(@lZ#;|KB-EXom4G z{?5{^Ef$`=^>nsdytqLcbLW=J*I-MkhiSgk-7(l+{lF0|I3>+i{ZMpVpl5ce2fs0W zQcFoNw{vMM>=r~+_PMl@fPf9R^it)#tyXD_NAxh^zA*O1CF=I>`Yr&}=mPLd_Z$JR zvUqiq0x0-&lSqS8O9xT$v9y`{=QJ>hUYgUCN=P2cmk(||0f~$a%A??$t{U=oM77x& zz-;Sj#CTkE?)p#F)ir&v7&1`ud?M27K@AU>>OPH-!Z-X3)*fHtk^=YV`FE~>jw;+_ z;u&_GACP@OOafxBI$Hd9Ae=ySjkf?6I-pc6>w{7OsB1JEBL08LX(})M|H)}8MyU?G z0LJVT=cFy_Vm1J>4S|UBeFtma9|KWpKx~cpIpn`_n@BJPT2n7j0T9gOJ;~S@7`wY! zrdn1zp`z?}C_iuJ#OFs97pEb70{~2CqatYA;v*Wc-dmH{49{i(2=9kl8xSr7GlTG% z{t?XUU}sZ?5#$20J{70eK6~W;{hv#fqQf8oS2zDDF39m%ugV`H$N^&kmlyjKaR-G} zlzfG(0dIpo_!0&){1+(5+@u)Dv*hzsinzwWUEJjL<4b_(yxtZL4frtNpSJ-3US(_< zWCP6DQ<3h!K}|w@Ul_ZFHRUw!@~GyYzYH74w}KIHMPkD&EwcHWr)t%G><47Q`FaZ~ zq1G_DwIn5h+yb^ZoC8?f(flX<)TG=&1!N-9v`V#W{iKazd_I9G}G1qy_R zevbI(#aRwqK+q%~8URQGxlY8Wrq}?6mHuqgBfW|V>4(qn1OP5A|A$O9p>yy9z@mZ6 zlHWRlf^aMJj~Hf@g7yCAPIN`>QglHUK>Db#02)R{4SvNMrxoDR#yqZ*;ZsCB?-V2b zC*E$^L5#GCpS8u!P7+QQ zB@@6b^6>|VUvb2IqT-TV^xU^z_EY1fafQ(cKE3!)3kR8I*2-N#%KQ9^ZYQ(@Gqc51 zVR%+h%tj<*L66sA74mSOL@$D9PozvoU8BtrX*g?6M?*?;;4nIZg%FE)7Z~cY4zl-m zF0k+Xsi-UlyY`!>oIvuSHoZu`w_VmjszkS+7aPZn5<77?nSa$}16?buyOo2|&%j+L z37E^cUWmLMRwEF@9>Ad9$tvyQY|KL~!CLzuQ7(|9DTiDHtSn}UNe;Rn2`8Ku$ zWOXrr`Ds}7KWSFoc$I(q*2`h6x!xD!3ovQ&=8yhDhB{A>A)*alVz>vGfYb6P+5g9yLTP&6eHy|1+)o3-_8A3x;UymH2 zxHNT&_Y8`T0ld&W9PH;5l_cA|SkFEurxTgFj7>!x`_iljAe;-Jx9RzsTM-~v`@(Q|0k0Z7;r0G$?G|Cn?U z+yHS>pV)^?x_qZTGIE|y1A)$RsIc=0#^jH!e+7f<#l=+&tRsHw;~!Sq(8+sMbNmgR zYF>*sS`}IN%fI?WHpS%&_Jae2QPWpPWL0~|dEn@H4uqf^0XN=?c39lD$&n^;M8+-n zCEpubUcRJ`Pc0MPTC)d+14s3-r7-ZK27WDY(W=*H!2RaEyo>sC{Mo-mEGXmTb881^ z?>pLQT?#-nL~#UYRWFpGr1*%(^ZlDFWpmA})pdD%ayuuqEp~mm6sy&JI$q7fB+gs! ze`GS6Z~1b))Zo@SJf3F&r_H8c<|%U%naWos@PGFik!O8naMv(vw1 ztT-b&1Q8VKq2!W{SuH@+IHA{sGgJKY0qdZ8j?Mu4u|1kZQ;g+FOnl?|+i#zW*s)8C zq@m=5L_sU%U?v9Jo1N1qWDu)>2;~dUSs3BZ6kuYjdO0YC;FwLI=v^Y8E@WSvY?K(` zR!-|%St+>gq~Z}F&rDGRixj=%$D^qWP_n9~L_|9(8C81CXW!sSoqtMTQ%4Phw=j~&Z&R(Osy<9d-5gK| zY?v6OU>N1;8~EtbVgy-Ep~^%@s#1KD!!WDv2&+;4c{56}gONA$W^qz!3F`p{+@`Nx zNyF{eK>tVn);jprbYNB&p}U3rTC4rhVKZ>KmqUtjHsw4yW7%K3XSYB8_$oApjB0fM z_7!nXhHp%?VBnzX3==4yf5oeQG)*Ob*yYh%u*2jPT-&okZf=XhHX$Bs=wFxu_H)Dv zD=%{F{RIk`5k%vAwFCIT|D97++YpB6k2RU9NYRV?zX6B+p00^$G*@eHsZR}GGP8iR zHFZv8`{QjL{k+%!+SclRi?`AJ=U)tM9g1HaPHOy=U66Q-~*ew-jt} z#Tl1?8ojUl=KhGorkrM3E4H5?#`I!4C$agwI#G7~LZm~eqmu4nvh?8^`lE^(Wp&GlWGzLJt0>ly&ezBTlVS7Q*Z|y&eb(^^d>gG5s5t5-dk_ z=X=|L*~aFLt=#(yf^tHG&s=u8VZN^O|Dbt#ea*K;$$SLLV)C)=;x~U|!^#`$sZ2h9 zEDs=(a4!97W>K;IKM8Dx-Jrj~XC>e5Irm!)>7R57+PbIdu!B4Un&Nuxy{9PD3sT~* zAzc9I2`IpWZ@v2RsSFk`vwtKwR3tiqlw_LAZDhuC;~b-Pr!v&A5u_jfg`FrVKKZ97BO8d@TspiVjEaW@ z93_2A-QT?YI(CxH6BMGS?pcIk#?E$_CEa+)vc z;-}?!zIuM}X}mZVfIJ<0zvpj#s|(uku+OO7h0;B&(;eID*4(%2fbBMVAUUnvZ6n?*nho?ny%c5-g#dh{u&5a%M_q3jZi;55UCVJ;J^(dV=3TLk9zhFIgC1g(8IB^)DtxTDUJ~;_1G>*^Qkyhh5eiSF3OLhm_&xX9u!$F_^m1;u7cHmfLNJUt~vp)U| z1H}0v@-2l{YkUJhs@sz=*A!kN-!X<;vE~{JgCy4SSqJ?j2V_VtVG^(u~^np00o zlr);fAzea4#8i|wkfDT^*8l8CqPXD{r7O>Dbq^$T-Q$S#FS_`jMeq!ggSAeT;JuT+pkU91doO=*t-A9r$N_WmiAqfki#1jEX zboS9Z+vR{J+sz1pfbh^#ne2Q5h-MglgbYpa-OC(i1POlQLoEE2 z#B5|gaI(*f&i*Y_6|Mz3H8WLYaN-;HKVZKf+$=AU(S`fbg}bLkcGKJ+hDK4z8?Qq& z7P@59v^@{x`oSN$St0D{u>|CN^`?g@mg?05&mT>j>Tgwj{{!(u9|I7-^CVL7JEryBMZ)KWkaOt9ZaCS=CPh!7Qsv%KgP zBo6xUsIkNWx)v+zGG=Yfiy*REAbnNM?IXbr!1g5f_AR6)9B};7GoKiI;&$Xat0`Om zb!Zn6h{J=@mc=JDesnGr<)M z%QvBx3Jy2=*GE8_wUFg{QmoCz*q3<=EvsKMft*XGs}^lwjZ8sS1*G!05`b8rOavUH~$j+692o^G#kA#dxO5?z5Q_w z$bH(t#?G#=4+6Z`y&a>;*!coMeiLEL`!^xkEIrZQaX(jx{>`a zHLIw+P7m8rQqdTfhX1Afai9E$@;9#bU&F)jI6Q!T{KpX^E5W0?aFN#o$U9YgBil44 zlJ{`AGwyLfw}ejl;4nmODIGj8u-hSEIOm*_bx+#ev^wtjiS<)SXwfVV z&ov^D4oah64%veE)nAJfVH1Q4r1=7JN#HBFkN({35a)4QNe?0B4*sMw{|oSxf#Krd z#ZQl~H?dj9)EW@?bfXw)?>7dLM3RV7{o`~bS(s0X1hr)~Kt7*^q4d8p?z^h8FS99= z$X9S6jcI|l!hZ7s7nOk{^|3A_H2$Rl;{W<@G(c`E%70p%n&D8yPX}^jx+qEw{1Q(B zFuIZEVhC5muib<*N<(#kKHSlj75)5C^K+4!T6q4K zU<~;jcNhmgUE62Hy2Ys}vtbrVztjdbE-L~B3x`B47IE#F+$8&M0i=eYP6W$mqu+PsTY>Li!O5BhD|7fw)Pu7pFr*NNKU-MJ7fwiBv0O zKTic}d)E#F!@aJ1D(~NGYo}OWpT!>?55l@lbrfr1H@+6|G?Tgg^?}d*?hXhwy!GQT zMoVjP?{5)A`715?oO^W->P>#ptQ@nQT<`Y6tkiZiqLD+eG*Vco9Cz)fgY|Qs8P-ou zjt4CbLuaB1cIBd5EL+2GX%|&I6IprMKyxrk0VeGrZe%_c1;D{fvv#)7sAkd0>IMUvf=Uvfi)C2Q<(vg_ez5OT&31_yXdV75s(;Ao8el|~$*a~*+RNMB&gQf&0MGg;YEYBlA$RrG4jWN|EiWgU~h(5j*N zCO+w~xjTzI&HVSTC$4A1o(h^^eIvS72Q(NWqzrUO1L0Bjr%_(sB?;n7n5vU6|Sci{8xXDh}iI7VTDuh z9xPdx?;7b7nKIb38ZkMtmhIDGUzREu)VYPDU?h`{d&s$_Rf~l#mRIg~C}}Ksx4&w# zwHh9kF8s2Ehi5RDKpMxx0ODC>%}i5}s*x7{QJXXt-#R&(B^mUFW6aW8;Br6oSMZvi z(U6q(XQtJZD#>ca3?FOO$5oQ}jy>VV=ntN#+GTX4Z%;zri&626d|^mXUl0^W2}hIK z^|KhdT+HryRe_zY($*!YoR!6f-H!BE3X?#E&X(3b3~WtgKf{E@44b};mVs@uFgb3_bTzirzRl4K5yi$R2CGcOm&19pAC>lIr>BSXhIzTVsN+#0+S-y<-Ye31_m|h`lgdy0?MZW`=jX8GaG!> zk(wEa?02I&-mo@5b9N81{kn}DkWN|4pjml>91s%P94ncTabh)_BcubZHlw=8a0A1) zK}b>P{o(X@Cfl7es@^BAmKESs_=c{AO0DO} zt=$waM9Arn6bF8W9`%q#rTYWpZ}R4lusO_(M1C$1hpzc4=!>BYsjq>M|zARev$ zE{pCjIlB2(WU0=+$I9jVYYp*33pJ~+{DBA_-``VyM%u6AM%QGqI{NC?qx$2{dVL_h zO;v8i^P`g($Ee8zy^5dJpq=P9KPgPY!|&QH#|UkWCU&!+4dtU;k4TEXN-AWzoC4$D ziY2$=_Q`o<$c9}XRLg48pKr$rDIZ#S3D9Jg6bTC_1n)ada>y7n{$5k!ZVI{X{HCav zoH|qmIMgO~Q=sTV$-zLCvXqD_;fS+?2>d^>2iV9Yp%kpw76Nv}J7|@BWbP{5T%#dZ z+&~5bzJe(`Q8yne*$VBk4VJYD`*1c)OR*$BJXM#fzU)#8o-4Vme$y8RE*(R=NqvK2 zbQ(cBP9w47wWqc`a}s$b85oGGRe`-wh2__730L1;5EcagV1gS}4ZIHgz7H^e0TGu? zFud2FSV~+rwR)Tuhk4ePp8lXQ#p-o_c6iGuCQ%do^_um&7m>fbi;e9$i%5TM=zYiQ zUZR|{WK|QgJjjj5OiwFWE2k%WJ$Jx52L?x7Q5{C#bF|@Btv@BXvLogbp+U@NTWy5e0o&t%)Hp; zNli2zE&JqqW>${KN{F=N3!9Z4x|n?AO<~aetwyJkM1Y)emy_=27L)~>PSiO@iKiWF|F5`ui zXN=u{zqYwi=p*8&*}SH*-D;_B8;FAws|I^#7FM(YFk_C{CwT9O2`h?N!x2gUg)g!S&BrxMbG3FjZ(YL@^_4|c|TTW1@unb?%Xh$5$d5&KnHoQYbz zy_TN_m8;_~<$_?uEv^5GsB7 z-8GoP3swv-&)h$6fa9mS?E0sXKdxWjRp0SFUr=EwBHY8938+>A&Mab4pniJSr&GM0 z3S%xe?I{J)Q-3;(qUl$4-l51us{Zws&fYX$(L`|L^q7)!dBE9@o(X2E*xSsHRqV2Y z@KRl|Z2?=iC;pe=b*F0V;F^P$emqNg7%+H?Omo*|J%_uD*M?yg%3OrV@B;=I?rm+A5uKtNpnuJn;5!vc21D`7 zrX6*eTQv`v-qeVN#=FF_AkA=!!Ij33idVTn*A7aTSN_t>@MD0f*iGkF|`B|*#s z{EQ;9$IUT6yim}*aru&`od;_k>k0uym$}Ix!`e}334Yj#qU1jQ%ItO!nUXzLa^8L( zs27(B)SG#mJVn+xpeD?oalX`4A#D`&|$) zU9h7CR<6!)wt6_o?HT*KSR(^!B6mx(PJu1~!9aB3H52pG+4%~Q_{Y_8V@`&aR^HM( zI6g73Fgj>Aan?CV_bS~W<9TV19WNq+w5mqPKJtWAKe9Fxf=AR=*4d;k+^9$;`W#5A z5`9Hx*?G)t?PtBPUr?4XhcMi%$gk!%gDM7aQN&U2?0v$)0CkuTu$Q z>s1HyidIUUJ2D7w5#P3@DQ?x^%wmUut_21KqArt5KV;^-288yzre&M&%h$EkE4i#) z&!Mza2tl!Mcl*GIf4vHK@hgI+rzhy%{$!RSG=6%L<~BF>q`c=tU)!tOTxc&o;k{b| zH3oS;`i<-HcVjQ9NmrDEj(hY0?Q$2N02i=YI0kW0*XS3!OD6Q)UQaXPcSHok49^}! zILzvDh>B7~_4|!7UwsP_C(qP>XF5xHaiH;P`!;8*`FF1Q{`+y$4ll$PO zAyk*S-(;u5macTL+HZvBQvWwT+x(-;!2#IP)3-Ra%}4m-^#bKIpK-8EJYCe^sZi2~ zlPZ=X8y+X&;w7pUUX8Yo0Q$+0s$JCZzW@BW_jL4RCr4&SuWktmEl zDJ)<_U}!w{tASx_6Xcp};qr=+E8 z)43&&Cdm|gI{F6UcsTx=Wj^(o9j^sC9PbxUQusiy`R;T#;mjfXi$2|!({8Dc$*Y4n z-EZ|34cU1A^v-99Z!e#XmxI;g9@S$Z&EXy4{Vmpf|0p$}R>ZG5Z%{uu(d4{vus;nw zij%8>-U=QZCCxL45Zh_c?B)}R$>XPso`TK=5;;|F{|KM2q0(?VSfsm}Blzq(_-v;2 zTr_D=D}&s8x9SNNO`by^H0yJ}Iqx3usWpve zY`U$xCJ~q&^xTOJ?wyZ`i8V^wTS6w`z@*Q8Q+$+_ie&+lW=P>f{n#!C(R@xp)e7?( z`DPIze1SbB=HGSbqP5<#A%F|!U&SZtoVfPZeNQaVFeP5ajOCT}RV4nf4MXYSmsf$; zWWu7j0)%Z6-z8gwJHM-2EmLem6K8j6lx!9!4+{b>C1V8#VLA)Wc^UndIfUc(ZoFbQ?z`vz}QwIjZ^fhH_Y`jcF=I?eL0S`sfcCP#MxZNr(Z4Fl{HCrd?_rZ zxF)HcpEC={n7VBjM#s|J+8{n$m(;DM7o}A25alxdfPELct(@qU@$0f)>|9Fp0^ZEm zLu7z+0a_-$gNCg>Uav5_=5#W%Hp!ayFnyJo_F|lMxn}Z`h5b6iRVuA)luWjii6(EE znKeop@&Ksej!~`g1Eb|BK&f%fnGvv)y2O!aU+)s|3>M!{TtLsRK1kDznOLX;0$lAs z^fbK1*6Ol|@mxN#)gF=-^*Us#)0g$g7C2qXNyoxtlT6;?d>!0L;BW_( z(>Oy}b@T#H48aCbj4vu406=a3c(8H*xRIiHX3OEEBz2Lc<5eD_I+2GQpS*xBCJ&Ut z$~t1I$#8$#z)s;prpV5aXtSz8<7s}1a>~Eoc~f_-7wA0yc|SolKBHcc*eq5!N=6(8 zmZUowXTMkkY|`Fuf{fg18CNuVkLOzuhU0EDVDYE%1hbeHy)b37_~|u>mE=U%MwXe+Pk-}GsLU1 zc&o=F_@|;w*r*wBzYS!6Y&KqU3P0a9V7`J3wqbso8|DNKSbJPB9C|%Bu#JPh#+-*2 z3{R{nBbs?NU-%K#W=gVFPa$`-eNku8+iq9I*H17L+J!#{yb*OEQ|uH7K`6ICqZ&W} zJm1f`&J$`iE{%LLsJI&_YGiL_KiFRz5?~4IbEzX4j>br!f(KfE|5DO_84; zurvN&W`S@g4Sw-EV~pGOx=p+W&eMaz!2>keO1)_tpJ;E-^}EoXv|GX>JucLSmU^BD zp5EsIS{rWiZq~*0fN690vGQC$Y7&v(@$|$H16WSh*0zS%!l%jyW?i6x=96LuwZ)@; zWIdytu57dqWAKbPc&k4LN%9tS&2(OHoYn1rr3SR8Brf-*% zZ;k!3s%iFMxtWmhWC+y!b&zAb32~?h!BRZmd`%#-fU%gy{p!K?A#=3>&lr_S2r{dY z(+kd(E$6#-)Fm14qs?<|Qk^f7H+%94!gPPRP4wo?`eIG&)x%F9i=Lh+e8UNhl{LMDbk(jVVkhSN%QC1 z1ph+jFwkw{ED-_(*&)_&=8bmv;60}%3=#mZ^;7oADmm2cYbdD zQ=Hoom34@9<+iAiym1YCJP<_hJ57~gKJ%RpXK2|1xc2z#Y^19h?ByrPr0`0MCD~Pp zt^SF_@F`pL1=SriTEBRY)xaPHcf7y-o^~*~a5<`(Z<)MY-OcpTOG#Jr*Hu1G`7xsc zS(-YFH%B?HC!THPe4Xy~l}MF2R_`m9SF`yqJ{eooBB^ayPGp@)J%mp!r*4k$mm^;H%p1b3fGg4GLBn4t zWD*TGO(d#oeni&52?=BGeDBQe@%~Xoz-=1)(bC0S0RP+E1^Pjw&u^wVjZ!3``x6#B zb;*iGJOsYD)X(v~6NIVyNNOZGKH`+IZn3HaXZx1-Qtc+M-60%ebZw=2^EPoZDHd)$ zJK;W8LVqf32975%n(ps)H6Pu8?}+xW~ zLAy4+#}#qvb8|s7v!fJ#3F0qgB_excRB)fo>HJDHeXSQPEfc$#Y37$OC%vs7iS92j zy7^sX_o!|!B^8{FnRH+=4X07=^>z&pEw*PLF)Yz{QCd)aDK;@a_24!Bk;+(cpvJw6 z(tB`SD<>wuFn~AYAIZ5QAV{{q`WYTFKc9$QPnKL)Bxz@Vi4+{tj)^xi9VwaX{p%M@ zV0&T50XU{zoALciMrk|SH5s@S$IAESSnN{G12i=i;<|?oiS_$7dfb<5S*7$da|qBD77K*e!s}z8sVsrrqU) zNl_o|>QzX7l0ExvAGvLKw{Um6A2UR#pBtm3A#(rh0MP-iET$LKrs+r*&7VKneoBis zu(P$%4|xQ2PTN4|(VAEN{cZJBDsv$V0XJ{@7Qem-bC^5*-9Um{M$SxElpE7So#W(X z&o9W6hW>>UvrPDV%wffi=4D`Rn8UT^pXrw$-o;T-vlJ4P zWied6i#Ip*45wI{&`Hnhjzh%UmbFFDCe8I_sNQujOD#)*@ku@w9yJ!!>?03nF3DXHnZ|r0q_Bj(y?KWRBF52SW z96iJE1GLIsE9lMRFPV|MvZs^BYy1(ZhJi`(&FPzW4Fo=IU{U~s2Mf~zg28LeMg{H$DO_}>`rjppZ4HSUJT?B?4El=q#`mND$F-0|o*=YGkRC?OUsh0D2+~1wE++L< zYD9jMQG0p>WbUZ=n)+{3Z?`P@ap(IcP>z3JhzS0Dm#ab8kdnH=HIM-t4$lYZZ%KD+ z!7|gqMBCWz0F5>U(Nk4taK_p<;8H{6)l;n>$eo5aj$br{|NeKRgYFvtMV#isdyC=9 z38nTrI%%ZDmmA!3{p9nr++QrFIyJV926Xm~^hm(^#8yYQ0fECaBfk?CqhpQGT&*nb z51qm_8om;=J&x(E-opX$8pbfHXJO$RrH?2e;|zXbir^ehfc01B%p}foj^V7X?7M2rnjm*IF0J0&X_Pb$;~s~#IRyu zd9)j#9@L0cs&B+#vXtY^I95S=f|HtENJ5`M8UjQ%@rq=mNZMW{H(V<%S4x!?g_0Y7 zzS!Ao2G+vJk@w^bj@<#xn_ij86_xB=UEa~TSJKBSlfkMVL~TT=F^p`Y<(*PmDpBah zo5&)WT;2|aNe0W3oAXX53uxZVEZh)-#bOt8Cmq`ZUZ)<*N#yK`3=4( zUmrK!+@a{t-J@RFBYIbz#hb%(ZF=%izass3bjZl|V zBd(un+V?~;TF!@7Wd8>jbzmiCcc3;)XvPB~rhS10KytKPz#+k6$jRa|@c!#W(OYJ8 zPFZoXpd@b>Gb}g6jWX1H(&ZD z+!~$@6a!6|h|C((%x3S@Uu9sjZ(6BdJ7ToMBRA8@pYK_*h{-5&)gi$@+wAslf?L*V zM#O^^?BBt3^y@^vl@B74vy!;@^R@=T*&u4&M^)mEm6pLXo!_{-jEFG}&}=Z^ZTZ-i zrRf|02)y*8UbVMc&Gp!Eu-bH>@~FpMaYx@gna0n?&gusYNW6mf5zu5T^Y?(F~{>DS&68lL}vGA3um?kk4km0 zeSTnJp~_ErsbK@a$^gY>k~+(NRCYtpzfv!LsJ@iqB!SGzRj zI5s$TeDM_n*)D^y^EK@wIy&D~C*KXG0c)+2+)$sR{#cJ#GJ{0DgMGkF|H@Q@;8k@` zclCXPZGU>@fLt+2gZ$X?n?=X7Hsj^Ti4**FE3O9Yv2J5)@eekH3}{UQkO}wuY2X72 z0YG^7%kWwKoL5(WH~_)Tb<=k8Cc9Lff)TJJf-Qm&${{UYa*1U<2p~?7T}B>4lE8i7 zn~0tdBB{G#=e?3alpU5hE}TEIf z3;!C^L(b{eScy?=T$a4V;S3q6^=qpQBnWKi7Z}dtyg5xz*bHn|lO}X?!|**}KBYDB zUC@MyR@S}PDFTEnEzi?^Wj!aHUeRjs_2)*0kz1TuKI_PLuWWR!7eF_%+Oj0Pq4}mh zpM!E0VSk`M3-%^8)y2xGFBO^;_>;D)?O?=?wVrQu zi%8YL)6WGf2U78)6Hhh!nk<3yj&al~*faZzCS(DNENy}eAEBFG&yb$m;lStmfYJTp z?tYx}`;aAYS`z*Gb||r-rjjK;`GSeumP$=CZdOvUT5)tweI0ppz0R$YdOFOqsskjD zzqBaEu8J*guXrkp+xX*h#75z%!yw{d*T(cJarcv5<;Q)^%={JD*WNv*$BIu_L)1&o z+&tVz39#eh>s)V`H(#@{7`29+_fH?TodQKee@;fvsOzspaC19ivhokpzV}0s0#fb%A0^_Ro=x=f4 zWMSAk^UW{6>gg8J6Ea(aN;+8aT9uwQYy-lIRmT|08~#HlO8qgPUu#dLb4;QB_g=(D-NoYjAw=yNa0{xF=Ki-)d{>$~;W$aB>JcuS;B{N-GTb^1E@ znD-XR)~-6;-Yp|N@c@J7bIhao-b*Yp--dC5^m}W8GmvmkEH#8WcYO* z)H+D0PvhE5r&UYE)BsU=>yWtg!C5;`+a>dY-Zyvlau4U-+c2XJu$3$4=SpN!=8Bsa#tJS3{B<5wG7 z?mzr~reWXF~R#JxK;`HS~-k_h>URYM;+h)1v!IbY5)KL literal 0 HcmV?d00001 diff --git a/talespin.pl b/talespin.pl new file mode 100644 index 0000000..87a9008 --- /dev/null +++ b/talespin.pl @@ -0,0 +1,104 @@ +/* Part of SWI-Prolog + + Author: Anne Ogborn + E-mail: anne@swi-prolog.org + WWW: http://www.swi-prolog.org + Copyright (c) 2018, Anne Ogborn + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +:- module(talespin, [ + story/4 + ]). +/** implements the Tale-Spin story generation algorithm + * + * 1. Plan + * 2. simulate plan moving forward. Randomly pick 'events', then + * have outcome be event's outcome, not action's outcome. + * 3. following an event, replan + */ +:- use_module(planner). + +%! story(+Init:list, +Genre:atom, +Options:List, -Story:list) is det +% +% @arg Init list of initial conditions +% @arg Genre module name of the story genre +% @arg Options Options list for plan/4 +% @arg Story bound to a story as a list of semantic occurances +% +story(Init, Genre, Options, Story) :- + repeat, % because of randomization story_ sometimes fails. + story_(Init, Genre, Options, Story), + !. +story_(Init, Genre, Options, Story) :- + plan(Init, Genre, Plan, Options), + simulate(Init, Genre, Options, Plan, XStory), + flatten(XStory, Story). + +simulate(_, _, _, [], []). +simulate(State, Genre, Options, [Action|Remains], [Desc | RemDesc]) :- + ( + event_happens(State, Action, Genre, Event) + -> + apply_action_dict(State, Event, NewState), + plan(NewState, Genre, NewPlan, Options), + Desc = Event.desc, + simulate(NewState, Genre, Options, NewPlan, RemDesc) + ; + Genre:action(Action, Dict), + apply_action_dict(State, Dict, NewState), + Desc = Dict.desc, + simulate(NewState, Genre, Options, Remains, RemDesc) + ). + +event_happens(State, Action, Genre, EventDict) :- + ( setof(Pair, possible_event(State, Genre, Action, Pair), Possible) + -> true + ; Possible = [] + ), + random_permutation(Possible, RandPossible), + maybe_pick_one(RandPossible, EventDict). + +maybe_pick_one([], _) :- !, fail. +maybe_pick_one([P-H | _], H) :- + P > random_float, + !. +maybe_pick_one([_ | T], Out) :- + maybe_pick_one(T, Out). + +possible_event(State, Genre, ActionName, Prob-Dict) :- + Genre:event(ActionName, Prob, Dict), + maplist(is_in(State), Dict.pre), + maplist(not_in(State), Dict.negpre). + +% famulus to swap memberchk's args +is_in(List, Member) :- + memberchk(Member, List). + +not_in(List, Member) :- + \+ memberchk(Member, List). +