% Author: Pascal Bercher % Version: 3.0 (2025-03-05) % % Change Log: % 2.0 -> 3.0 % - Added causalLink label macro % - Removed code duplication % - Renamed files and folders standardized naming % - Revised instructions % Load necessary packages and styles \RequirePackage{tikz} \RequirePackage{listofitems} % Load required TikZ libraries directly \usetikzlibrary{calc, positioning, decorations.pathreplacing, decorations.markings} % this allows the definition of causal links, which place dots on the start and end of the link \tikzset{ causalLink/.style={ ->, shorten <= 0.15cm, shorten >= 0.15cm, postaction={ decorate, decoration={ markings, % Not using exaxtly 0 and 1 is a hack sugested by chatGPT % because otherwise for long links the goal dots are not placed mark=at position 0.0001 with {\fill circle[radius=1pt];}, mark=at position 0.9999 with {\fill circle[radius=1pt];} } } } } % Name of Action/.style n args={number of objects}{ % {action= % % number of precs/effs % {num of precondition lines (on the left side of action)} % {num of effect lines (on the right side of action)} % % prec/eff labels % {sequence of precondition labels} % {sequence of effect labels} % % length of precs/effs % {length of preconditions} % {length of effects} % % action name % {action name} % % prec/eff label position % {precondition/effect label position: side or top} % {height of node} % } \tikzset{ action/.style n args={9}{ draw, rounded corners, minimum width=3cm, fill=cyan, minimum height={#9}, label={center:#7}, append after command={ \pgfextra{ % Define the node name \edef\nodename{\tikzlastnode} \ifx#3\empty % Check if label list is empty \else % Process only if not empty % Read the label content \setsepchar{,} \readlist\nameparts{\nodename} \setsepchar{,} \ifnum#8=0\relax % Define positions for preconditions and effects relative to the node with shifts \ifnum#1>0 \readlist\labellist{#3} \foreach \i in {1,...,#1} { % Precondition coordinates and lines \coordinate (\nodename-pre-\i) at ([xshift=-#5cm, yshift=#9/2-#9/(#1+1)*(\i)] \nodename.west); \draw (\nodename.west |- \nodename-pre-\i) -- +(-#5,0) node [midway, above, sloped, font=\scriptsize] {\labellist[\i]}; } \fi; \readlist\labellist{#4} \ifnum#2>0 \foreach \j in {1,...,#2} { % Effect coordinates and lines \coordinate (\nodename-eff-\j) at ([xshift=#6cm, yshift=#9/2-#9/(#2+1)*(\j)] \nodename.east); \draw (\nodename.east |- \nodename-eff-\j) -- +(#6,0) node [midway, above, sloped, font=\scriptsize] {\labellist[\j]}; } \fi; \else \ifnum#1>0 \readlist\labellist{#3} \foreach \i in {1,...,#1} { % Precondition coordinates and lines \coordinate (\nodename-pre-\i) at ([xshift=-#5cm, yshift=#9/2-#9/(#1+1)*(\i)] \nodename.west); \draw (\nodename.west |- \nodename-pre-\i) -- +(-#5,0) node [xshift=-(#5+0.5cm), sloped, font=\scriptsize]{\labellist[\i]}; } \fi; \readlist\labellist{#4} \ifnum#2>0 \foreach \j in {1,...,#2} { % Effect coordinates and lines \coordinate (\nodename-eff-\j) at ([xshift=#6 cm, yshift=#9/2-#9/(#2+1)*(\j)] \nodename.east); \draw (\nodename.east |- \nodename-eff-\j) -- +(#6,0) node [xshift=(#5+0.5 cm), font=\scriptsize] {\labellist[\j]}; } \fi; \fi; \fi; } }, label content/.initial={#3} } } % INIT/.style={ % init={ % {number of effects}, % {effects}, % {effects length}, % {height of init}}} % GOAL/.style={ % goal={ % {number of preconditions}, % {preconditions}, % {preconditions length}, % {height of goal}}} \tikzset{ base/.style n args={6}{ draw, minimum width=0.05cm, fill=black, minimum height={#6}, append after command={ \pgfextra{ \edef\nodename{\tikzlastnode} \setsepchar{,} \readlist\labellist{#2} \foreach \i in {1,...,#1} { \coordinate (\nodename-#5-\i) at ([xshift=#3 cm, yshift=#6/2-#6/(#1+1)*(\i)] \nodename.#4); \draw (\nodename.#4 |- \nodename-#5-\i) -- +(#3,0) node [midway, above, sloped, font=\scriptsize] {\labellist[\i]}; } } } } } \tikzset{ % Init style init/.style n args={4}{ base={#1}{#2}{#3}{east}{eff}{#4} } } \tikzset{ % Goal style goal/.style n args={4}{ base={#1}{#2}{-#3}{west}{pre}{#4} } }