123456789101112131415161718192021222324252627282930313233343536373839404142434445464748(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)type('context,'action)t=|Actionofstring*'action|Conditionofstring*('context->bool)|Sequenceof('context,'action)tlist|Selectorof('context,'action)tlist|Notof('context,'action)t(* one evaluation: success or not, the action decided (the last one on
* the successful way), and the nodes visited, most recent first *)letreceval(tree:('context,'action)t)(c:'context)(seen:(string*bool)list):bool*'actionoption*(string*bool)list=matchtreewith|Action(label,a)->(true,Somea,(label,true)::seen)|Condition(label,q)->letok=qcin(ok,None,(label,ok)::seen)|Sequencechildren->letrecgodecidedseen=function|[]->(true,decided,seen)|child::rest->letok,a,seen=evalchildcseeninifnotokthen(false,None,seen)elsego(ifa=Nonethendecidedelsea)seenrestingoNoneseenchildren|Selectorchildren->letrecgoseen=function|[]->(false,None,seen)|child::rest->letok,a,seen=evalchildcseeninifokthen(true,a,seen)elsegoseenrestingoseenchildren|Notchild->letok,_,seen=evalchildcseenin(notok,None,seen)letdecidetreec=matchevaltreec[]withtrue,a,_->a|false,_,_->Noneletpathtreec=let_,_,seen=evaltreec[]inList.revseen